Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🌿 Apresentação

Você chegou ao PAEBIRU — Protocolo Assíncrono de Ecossistemas Biológicos para Infraestruturas Recursivas Universais. Esta documentação é a fonte canônica de verdade. Está organizada em três trilhas — escolha a que combina com o seu momento.

flowchart LR
    A[Quem é você?] --> B{Primeira vez?}
    B -- Sim --> C[🌱 Estou chegando<br/>README · MANIFESTO<br/>ROADMAP · SETUP]
    B -- Não --> D{Operando em campo?}
    D -- Sim --> E[🔧 Vou operar<br/>Runbooks · Flashing<br/>Observabilidade]
    D -- Não --> F[🛠️ Vou contribuir<br/>RSE · 4 Dogmas<br/>RFCs · Bounded Contexts]

🌱 Estou chegando

Você nunca trabalhou com o PAEBIRU antes — perfeito. Comece por aqui.

PassoO que lerO que fazer
1ManifestoEntenda a visão: por que outra plataforma P2P?
2RoadmapSaiba em que fase estamos (Fase 1 — Fundação da Névoa)
3Setup inicialInstale o toolchain (Nix recomendado)
4Primeiros passosSuba um nó, escreva um plasmídeo, converse com a malha

Glossário essencialmalha, GALS, Maturidade Causal, Algedonic, LandauerLedger, Estigmergia — definidos no Dicionário canônico. Volte a ele sempre que um termo parecer novo.


🔧 Vou operar

Você é operador de campo: o nó está implantado, o termostato está a 65 °C no armário de telecom e o pager tocou às 3h. Esta trilha é o seu manual.

NecessidadeVá direto para
O nó não sobeR001 · Boot de nó em campo
Identidade / TPMR002 · Identidade TPM
Rotação de chavesR003 · Rotação FROST
Ledger corrompidoR004 · Recuperação de ledger
Pacote suspeitoR005 · Quarentena MacrophageVM
Atualização OTAR006 · Atualização OTA
Tráfego DDoSR007 · Saturação XDP
Drift de relógioR008 · Langevin clock drift
Migrar para OceanoR009 · Migração para Oceano
ZK-PoL falhouR010 · Falha de ZK-PoL
Desastre totalR011 · Disaster recovery

Para o ciclo completo, comece pelo Caderno do operador.


🛠️ Vou contribuir

Você é engenheiro(a) — quer modificar o código, abrir uma RFC, ou entender a arquitetura. Esta trilha é o seu guia.

Para entender a forma do organismo:

Para entender o porquê teórico:


🗺️ Onde encontrar o quê

PerguntaResposta
O que é o PAEBIRU?Manifesto
Em que pé está?Roadmap
Como instalo?Setup
O que significa X?Dicionário
Como funciona Y?Bounded Context de Y
Como operei?Runbooks
Como contribuir?Guia de contribuição
Como reporto segurança?Política de segurança

📐 Convenções editoriais

Esta documentação segue convenções estritas (§9 do AGENTS.md):

  • kebab-case em nomes de arquivo (exceção: rfcNNN_*.md).
  • Metadados em comentários HTML (<!-- title: ... -->), nunca em frontmatter YAML — o mdBook renderiza YAML como texto visível.
  • Caminhos relativos em todos os links. Caminhos absolutos são proibidos (a CI quebra o build).
  • Diagramas em Mermaid (code-first), não imagens binárias.
  • Português brasileiro (pt-BR) como idioma principal; termos técnicos canônicos são obrigatórios.

🌐 Onde nos encontrar


📜 Manifesto

Por que construir outra plataforma de computação distribuída quando já temos tantas? Esta é a resposta em sete teses.


Tese 1 — Soberania é um problema arquitetural, não político

A soberania computacional não emerge de declarações: emerge de decisões de projeto. Se a sua identidade mora em um servidor de CA privado, a sua soberania é a soberania daquele operador. Se a sua chave mora na sua cabeça ou no seu TPM, a sua soberania é sua.

PAEBIRU assume soberania por design:

  • Identidade enraizada em hardware (TPM 2.0, Secure Enclave).
  • Criptografia pós-quântica como linha de base, não como migração futura.
  • Zero-Trust como postura default, não como feature configurável.

Tese 2 — A biologia já resolveu quase tudo

A natureza roda, há 4 bilhões de anos, uma rede distribuída com:

  • 10³⁰ ~ 10³¹ células vivas, sem nenhum CEO.
  • Tráfego massivo de informação (sinapse, hormônio, quórum), sem backbone central.
  • Resiliência a perda de nós (apoptose, necrose, regeneração).
  • Identidade verificável (sistema imune) sem autoridade emissora global.

PAEBIRU estuda esses mecanismos em vez de reinventar:

  • Metabolismobackpressure e LandauerLedger.
  • Imunidade → MacrophageVM e síntese de anticorpos (plasmídeos WASM).
  • Estigmergia → coordenação indireta via receipt e rastro ambiental.
  • Homeostasia → sensores algedônicos em cada escala, sem supervisor global.

Tese 3 — O nó mais simples deve ser o mais simples possível

Se um sensor LoRaXBee com 32 kB de RAM não consegue participar da malha como igual, o sistema não é distribuído — é centralizado com participação periférica. O PAEBIRU é executável, sem std, em:

  • ATmega 328P (8 bits, 2 kB RAM) — via paebiru-hal com heapless.
  • ESP32, STM32, nRF52 — Cortex-M com FPU.
  • RISC-V rv32imc (energy harvesting).
  • x86 / arm64 em servidores e mainframes.

A mesma malha fala com todos; cada um fala só o que sua banda permite.


Tese 4 — Coordenação sem carona (anti-padrão “Costura”)

Bounded Contexts se comunicam por artefatos imutáveis com receipt, nunca por Arc<Mutex<T>> cruzando a membrana. “Costura” — acoplamento por tipo ou estado compartilhado — é sintoma de fronteira mal colocada.

A regra é cirúrgica: refatore a membrana antes de adicionar mais código. Nenhum patch que costure contextos é aceito.


Tese 5 — Tempo é maturidade, não cronologia

Ordenação de eventos usa Dotted Version Vectors (DVV) e Maturidade Causal, não Instant::now(). Em regime futuro (Dança Politemporal), Δt ∝ ΔS/γ — o tempo “congela” na ausência de variação entrópica.

Isso não é teoria: é a única forma de coordenar agentes que vivem em redes com partições, drift de relógio e backpressure variável sem liveness falso-positivo.


Tese 6 — A energia é a moeda primária

Computação não é gratuita. Cada ciclo é um joule subtraído do planeta, e cada joule é mensurável, debitável e auditável. O LandauerLedger transforma esse débito em receipt verificável — a base do crédito mútuo e da Loteria Joule (tópico em formalização).

A Loteria Joule não é uma metáfora: é o mecanismo pelo qual o sistema recompensa quem contribuiu com poder computacional real, em ordem causal, e cobra de quem drenou a malha.


Tese 7 — A fractalidade é restrição, não estética

O ciclo ingerir → metabolizar → excretar repete-se em 7 escalas — bit físico → neurônio LIF → função WASM → plasmídeo → nó ABAPORU → LocalSyncDomain → malha global. Esta é a Restrição Antropofágica (Realidade fractaltópico em formalização):

  • Mesma forma, em 7 escalas.
  • Mesmas propriedades emergentes: homeostasia, algedonia, receipt.
  • Mesmas ferramentas: Maturidade Causal, backpressure, estigmergia.

Quem viola esta restrição introduz uma articulação: a malha fica mais frágil, não mais rica.


Conclusão — Por que agora?

Porque a próxima década será de coordenação, não de comando. Porque infraestrutura crítica (saúde, energia, água, alimentos) precisa ser soberana por design, não por contrato. Porque o planeta não aguenta mais uma camada de abstração que ignora termodinâmica.

O PAEBIRU não é um produto. É um protocolo-cérebro — uma membrana metabólica entre humanos, dispositivos e a energia que os move. Se você concorda com pelo menos quatro destas teses, esta malha é sua também.


Veja também

🗺️ Roadmap

Quatro fases, da névoa à maturidade, com meta de finalização até 2026-12-31. Esta página é a fonte canônica de verdade sobre onde estamos e para onde vamos. O mapeamento granular por crate × fase está em Mapeamento do workspace.

Modo de operação: time pequeno + agentes de IA (Claude Code, Gemini CLI, kimi-cli, scripts) acelerando boilerplate, testes, documentação e verificação. Decisões arquiteturais e revisão continuam humanas. Veja CONTRIBUTING.md §3.

gantt
    title PAEBIRU · Roadmap 2026 (release v1.0.0 em 2026-12-31)
    dateFormat YYYY-MM-DD
    axisFormat %Y-%m
    section Fase 1 · Névoa
    Relé DHT autônomo              :active, p1a, 2026-06-05, 14d
    Edge scheduler + backpressure  :p1b, after p1a, 14d
    Island mode                    :p1c, after p1b, 14d
    section Fase 2 · Resiliência
    Identidade TPM 2.0 + quote     :p2a, after p1c, 14d
    FROST DPSS                     :p2b, after p2a, 14d
    WAL + tiering (C.A.P.I.B.A.)   :p2c, after p2b, 14d
    section Fase 3 · Economia
    Metering real (Landauer)       :p3a, after p2c, 21d
    Spot market + Loteria Joule    :p3b, after p3a, 21d
    Testbed físico (LoRa/Modbus)   :p3c, after p3b, 14d
    Chaos engineering              :p3d, after p3c, 7d
    section Fase 4 · Maturidade
    ML no scheduler (FLAIR)        :p4a, after p3d, 28d
    WASI-PAEBIRU ABI estável       :p4b, after p4a, 21d
    Certificações HW (CE/FCC)      :p4c, after p4b, 28d
    Piloto (saúde / água / energia):p4d, after p4c, 14d
    section Release
    v1.0.0 · freeze + publish      :crit, r1, 2026-12-25, 7d

Cores no Gantt: vermelho = crítico (release), preenchido = em curso.


Estado atual: Fase 1 — Fundação da Névoa (em curso)

⚠️ O workspace Cargo desta release contém apenas apps/node e crates/kernel. Os demais 30 crates descritos no AGENTS.md são visão ratificada, mas ainda não implementados. Os agentes de IA estão acelerando a implementação seguindo o CONTRIBUTING.md e o skill paebiru-architect.

MarcoStatusMarco de finalização
Toolchain nightly + Nix flakeflake.nix, rust-toolchain.toml
paebiru-kernel (GALS/actor, ports, adapters)estrutura hexagonal inicial
paebiru-node (daemon libp2p)tokio + libp2p + tracing
Relé DHT autônomo🔄 em curso2026-06-19
Edge scheduler com backpressure2026-07-03
Island mode2026-07-10

Política de release: não marque seu PR como v1 a menos que feche um ciclo ponta-a-ponta. Em caso de dúvida, consulte workspace-mapping.md.


Fase 1 — Fundação da Névoa (F1)

Janela: 2026-06-05 → 2026-07-10 (5 semanas) Status: em curso

Tema: conectividade básica, scheduling, observabilidade.

Objetivos:

  • Relé autônomo via DHT — qualquer nó novo se anuncia e é descoberto.
  • Edge scheduler com backpressure (token bucket, créditos).
  • Island mode — operação isolada em cenários sem WAN.
  • Observabilidade ponta-a-ponta (Jaeger + Prometheus + Grafana).

Marcos (gates de saída):

  • 2026-06-19 Relé DHT: dois nós trocam pulse ponta-a-ponta via libp2p Kademlia.
  • 2026-07-03 Edge scheduler: token bucket ativo; MetabolicAction::Saturated testado com proptest.
  • 2026-07-10 Island mode: nó sobrevive 7 dias offline e drena backlog ao reconectar.

Critérios de saída (DoD da F1):

  • Dois nós trocam receipts soberanos ponta-a-ponta, com PAEBIRU_SKIP_PF=false.
  • Um nó sobrevive 7 dias sem WAN, drenando backlog ao reconectar.
  • Dashboard Grafana exibe: latência, backpressure, LandauerLedger, alarmes algedônicos.
  • Cobertura ≥ 90 % nos crates kernel e node.
  • Compila para riscv32imc-unknown-none-elf e thumbv7em-none-eabihf.

Fase 2 — Resiliência e Multi-Tenancy (F2)

Janela: 2026-07-10 → 2026-08-21 (6 semanas)

Tema: quotas, attestation, secrets, WAL, tiering.

Marcos (gates de saída):

  • 2026-07-24 Identidade TPM 2.0 com tpm2_quote; sem fallback em produção.
  • 2026-08-07 FROST DPSS: 3-de-5 assinaturas; rotação testada (R003).
  • 2026-08-21 WAL posix + tiering (quente → morna → C.A.P.I.B.A. → Oceano).

Critérios de saída:

  • Identidade enraizada em hardware é verificável por qualquer nó sem CA.
  • Recuperação de ledger após corrupção (R004) automatizada.
  • 100 nós com quotas heterogêneas operam 30 dias sem deadlock algedônico.

Fase 3 — Economia Real e Hardware (F3)

Janela: 2026-08-21 → 2026-10-09 (7 semanas)

Tema: metering, spot market, drivers reais, testbed físico, chaos.

Marcos (gates de saída):

  • 2026-09-11 LandauerLedger debitando em µJ (PAEBIRU_GATE_SECURITY_COST_MICRO_JOULES) por operação de portão.
  • 2026-10-02 Spot market + Loteria Joule com compensação multilateral a cada 24h.
  • 2026-10-09 Drivers LoRa SX1262 + Modbus RTU + CAN bus operacionais no testbed físico.

Critérios de saída:

  • Um nó em campo com sensor LoRa+Modbus envia receipt soberano que outro nó consegue validar e usar como prova de crédito.
  • Loteria Joule opera 90 dias sem inconsistência de soma zero.
  • MacrophageVM captura um pacote malicioso real do testbed e gera anticorpo.

Fase 4 — Maturidade (F4)

Janela: 2026-10-09 → 2026-12-25 (11 semanas)

Tema: otimização, padronização, ecossistema.

Marcos (gates de saída):

  • 2026-11-06 ML no scheduler (FLAIR/Ising, Langevin SGD) com ≥ 30 % de redução de latência P99.
  • 2026-11-27 WASI-PAEBIRU ABI congelada (12 semanas de estabilidade).
  • 2026-12-25 Certificações HW (CE, FCC, Anatel) iniciadas; piloto em 1 domínio público operando ≥ 30 dias.

Critérios de saída:

  • WASI-PAEBIRU ABI congelada por 12 meses sem quebra.
  • Piloto em 1 domínio público (saúde, água ou energia) operando ≥ 30 dias.
  • 1 000 nós heterogêneos (ATmega → mainframe) na malha global.

Escopo de F4 comprimido: para fechar em 2026-12, reduzimos o critério “1 000 nós na malha” para uma meta de strain-test interno (≥ 100 nós simulados + 10 físicos). O marco de 1 000 nós reais fica para v2.0 em 2027-Q2. Veja RFC em formalização · Roadmap v1.


Release v1.0.0

Janela: 2026-12-25 → 2026-12-31 (1 semana, freeze)

Janela de code freeze + auditoria de segurança + publicação. Tudo o que não entrou até 2026-12-24 vira v1.1.0 em 2027-Q1.

AtividadeDonoDuração
Code freeze (branch release/v1.0.0)maintainer1 dia
cargo audit + cargo vet + revisão de segurançasegurança2 dias
Geração de binários cross (Linux x86_64/aarch64/riscv64, macOS, Windows)release1 dia
Publicação Docker Hub + GitHub Release + tagsrelease1 dia
Anúncio + post-mortem do ciclomaintainer2 dias

Por que 6 meses é viável

  • Agentes de IA (Claude Code, Gemini CLI, kimi-cli) aceleram tarefas mecânicas: scaffolding de crates hexagonais, geração de testes, escrita de docs, verificação de tipos, lint, cobertura.
  • Skills versionadas (.agents/skills/paebiru-*) capturam o conhecimento de domínio e o tornam executável pelos agentes.
  • Templates canônicos (TLA+, Lean 4, BC docs, RFCs) reduzem o tempo de “página em branco”.
  • Política de imutabilidade relaxada durante a fundação — renumeração de RFCs DRAFT é permitida até ratificação.
  • Cobertura ≥ 90 % é o gargalo real, não a velocidade de escrita: cada crate precisa de testes substanciais.

O que não está no escopo deste roadmap

  • Bindings de 13 linguagens — apenas paebiru-c (estável) e paebiru-py (beta) entram em v1.0.0. Demais ficam para v1.1+.
  • Hardware wallet de prateleira — F4 entrega apenas o design de referência; a produção fica para 2027.
  • DAO on-chain — governança fica off-chain (FROST + assinaturas multi-partidárias) em v1.0; on-chain migra em v2.0.
  • ML no scheduler além de FLAIR — a integração com modelos externos (Candle, LLMs locais) fica para v1.1+.

Como ler este roadmap

Se você é…Leia também
OperadorCaderno do operador
ContribuidorMapeamento do workspace
PesquisadorFundamentos
Decisor / financiadorManifesto

Versão: 2.0 · Última atualização: 2026-06-05 · Próxima revisão: quinzenal · Mudanças versionadas por git tag (roadmap-vN).

⚙️ Setup inicial

Do zero ao cargo run -p paebiru-node em 15 minutos se você está em Linux x86_64 com Nix. Outras plataformas exigem instalação manual das deps de sistema.


Caminho 1 — Nix (recomendado)

Obtém todo o toolchain: Rust nightly, TPM2-TSS, libbpf, CUDA opcional, cross-compile para RISC-V e Cortex-M, Python, Node, Zig, PHP, R, Ruby, .NET 8, JDK 17, Dart, Go. Reproduzível bit-a-bit entre máquinas.

Pré-requisitos

  • Nix com flakes habilitados.
  • ~3 GB de espaço em disco para o shell.

Comando único

git clone https://github.com/paebiru/paebiru.git
cd paebiru
nix develop               # entra no shell
make build                # build do workspace default
make test                 # roda a suíte

Ao entrar no shell você verá:

🌿 Bem-vindo ao ambiente de desenvolvimento PAEBIRU (Nix)
Rust: rustc 1.86.0-nightly (...)
TPM2-TSS e Vulkan configurados.

Dica (CI): use nix develop --command bash -c 'make pre-commit' em scripts de CI.


Caminho 2 — Manual (Debian / Ubuntu 24.04)

Use este caminho se você não pode instalar Nix. Leva ~30 min.

1. Dependências de sistema

sudo apt-get update
sudo apt-get install -y \
    build-essential git curl pkg-config \
    libbpf-dev clang llvm libtss2-dev libssl-dev \
    cmake

2. Rust (nightly)

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
. "$HOME/.cargo/env"
rustup toolchain install nightly --profile minimal
rustup component add rust-src rust-analyzer llvm-tools-preview clippy rustfmt
rustup target add riscv32imc-unknown-none-elf \
                thumbv7em-none-eabihf \
                wasm32-unknown-unknown

O rust-toolchain.toml na raiz fixa a versão exata do nightly. Não instale stable — o projeto usa Edition 2024 + features instáveis (no_std em MCUs).

3. Ferramentas Cargo

cargo install cargo-llvm-cov cargo-audit cargo-fuzz

4. Pre-commit

pip install pre-commit mdbook mdbook-mermaid
pre-commit install

5. Verificação

make check       # cargo check rápido
make test        # roda a suíte
make pre-commit  # hooks locais

Caminho 3 — macOS

brew install git pkg-config openssl@3 bpfcc libbpf llvm tpm2-tss
# ...em seguida o mesmo rustup/cargo install do caminho 2

macOS não suporta eBPF/XDP nativo. O Portão 1 (Load Shedder) é automaticamente desabilitado na detecção do Darwin; em produção, use um nó Linux como edge.


Caminho 4 — Windows (WSL2 recomendado)

A matriz de release é Linux-first. Windows é suportado via WSL2 (Ubuntu 24.04). O caminho nativo é experimental.

wsl --install -d Ubuntu-24.04
wsl
# dentro do WSL2, siga o Caminho 1 (Nix) ou 2 (manual)

Variáveis de ambiente

VariávelDefaultSignificado
PAEBIRU_STORAGE_PATH~/.paebiruPersistência (identidade, ledger, backlog)
PAEBIRU_API_PORT1975Porta da API HTTP/observabilidade
PAEBIRU_SKIP_PFfalseNUNCA true em produção (desabilita portão XDP)
PAEBIRU_SKIP_TRACERfalseNUNCA true em produção (desabilita OTel)
PAEBIRU_SKIP_GEO_DISCOVERYfalsePula descoberta de geolocalização (use em CI)
PAEBIRU_SKIP_GPU_TESTSfalsePula testes com CUDA (use em CI)
RUST_LOGinfoVerbosity: trace · debug · info · warn · error

Subir um nó local

cargo run -p paebiru-node

Saída esperada (em ~5 s):

NODE  Iniciando PAEBIRU Node (Trilha de Aço)...
NODE  Ponta-a-ponta rodando. Aguardando descoberta de peers...

Em outro terminal:

make test-local     # ciclo de vida ponta-a-ponta
# ou
curl http://localhost:1975/healthz

Para parar: Ctrl-C. O nó faz shutdown gracioso, fechando receipts em aberto e liberando peers.


Próximos passos


Solução de problemas

SintomaCausa provávelSolução
error: linking with 'cc' failed em macOSXcode CLT ausentexcode-select --install
couldn't find libbpflibbpf não instaladoapt install libbpf-dev ou brew install libbpf
toolchain 'nightly-...' is not installedrustup não tem nightlyrustup toolchain install nightly
permission denied em /var/run/tpm0TPM não presenteesperado em dev; em produção use nó com TPM 2.0
Porta 1975 ocupadaOutra instância rodandolsof -i :1975 ou mude PAEBIRU_API_PORT
mdBook não renderiza Mermaidmdbook-mermaid ausentecargo install mdbook-mermaid

Se persistir, abra issue no GitHub com a saída completa de nix develop --command bash -c 'make pre-commit 2>&1'.

⚙️ Instalação

O PAEBIRU utiliza um toolchain moderno baseado em Rust Nightly e Nix. Se você já tem o Nix instalado, o processo leva menos de 5 minutos.


🚀 Caminho Rápido (Nix)

Recomendado para Linux e macOS. O Nix garante que você tenha as versões exatas de todas as dependências, incluindo compiladores para sistemas embarcados.

  1. Instale o Nix (se ainda não tiver):
    curl -L https://nixos.org/nix/install | sh
    
  2. Habilite Flakes (adicione ao seu ~/.config/nix/nix.conf):
    experimental-features = nix-command flakes
    
  3. Entre no ambiente:
    git clone https://github.com/paebiru/paebiru.git
    cd paebiru
    nix develop
    

Ao entrar, você verá a mensagem: 🌿 Bem-vindo ao ambiente de desenvolvimento PAEBIRU (Nix)


🛠️ Caminho Manual (Ubuntu/Debian)

Se preferir não usar Nix, você precisará instalar as dependências de sistema e o Rust manualmente.

1. Dependências de Sistema

sudo apt update
sudo apt install -y build-essential git curl pkg-config libbpf-dev clang llvm libtss2-dev libssl-dev cmake

2. Rust Nightly

O PAEBIRU exige a edição 2024 e funcionalidades instáveis do Rust.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup toolchain install nightly
rustup default nightly
rustup target add riscv32imc-unknown-none-elf thumbv7em-none-eabihf wasm32-unknown-unknown

✅ Verificação

Para garantir que tudo está funcionando, rode o comando de verificação rápida:

make check

Se o comando terminar com Finished, seu ambiente está pronto para a Próxima etapa.


❓ Problemas comuns

  • libbpf não encontrada: Certifique-se de instalar libbpf-dev.
  • Erro de target: Verifique se você adicionou os targets riscv32 e thumbv7 via rustup.
  • TPM2: Em máquinas virtuais, o suporte a TPM2 pode falhar; isso não impede o desenvolvimento inicial, mas é necessário para identidade soberana em produção.

Para um guia exaustivo de variáveis de ambiente e suporte a outras plataformas (Windows/macOS), veja o Setup Detalhado.

🧬 Primeiro plasmídeo

No PAEBIRU, a lógica de aplicação não vive em servidores centrais, mas em plasmídeos — pequenos módulos WASM que viajam pela malha e são executados pelos nós.


🧐 O que é um plasmídeo?

Inspirado na biologia, um plasmídeo é uma unidade auto-contida de código e dados.

  • Definição: Escrito em uma DSL (Domain Specific Language) baseada em TOML ou HCL.
  • Execução: Compilado para WebAssembly (WASM) e executado de forma isolada (sandbox).
  • Distribuição: Propagado via GossipSub para os nós interessados.

📝 Definindo o plasmídeo

Um plasmídeo simples de “Hello Mesh” que emite um log quando recebe um pulso:

# hello_mesh.toml
[plasmid]
name = "hello-mesh"
version = "0.1.0"
author = "Soberano <node@exemplo.org>"

[behavior]
on_pulse = """
    log::info("Olá, malha! Recebi um sinal de {}", context.sender);
"""

🛠️ Ciclo de Vida

  1. Sintetizar: O comando paebiru plasmid build converte o TOML em um binário .wasm.
  2. Assinar: O plasmídeo é assinado com sua identidade soberana (Portão 3).
  3. Injetar: Você injeta o plasmídeo no seu nó local.
  4. Propagar: O nó anuncia o novo plasmídeo para a vizinhança causal.

🛡️ Segurança (Zero-Trust)

Antes de ser executado por qualquer nó, o plasmídeo passa pelo ZeroTrustPipeline:

  • Portão 5: Validação semântica do contrato de dados (CDDL).
  • MacrophageVM: Execução em quarentena para análise de comportamento.

🏁 Parabéns!

Você completou a trilha de Primeiros Passos. Agora você entende a visão, instalou o ambiente, subiu um nó e conhece as ferramentas de gestão e computação do PAEBIRU.

Para onde ir agora?

🛠️ Forge CLI

A Forge CLI (paebiru-cli) é a canivete suíço do ecossistema PAEBIRU. Ela permite gerenciar identidades, monitorar nós em tempo real e realizar o flash de firmware em dispositivos embarcados.


📋 Visão Geral

A CLI foi projetada para ser tanto uma ferramenta de script quanto uma interface visual rica (TUI) para operadores de campo.

Comandos Planejados

ComandoDescrição
paebiru node statusExibe o estado de saúde, peers conectados e backpressure.
paebiru identity genGera uma nova identidade soberana (enraizada em hardware se disponível).
paebiru identity exportExporta a chave pública/PeerID para a malha.
paebiru flashFerramenta de flashing para ESP32, STM32 e RISC-V.
paebiru dashboardInicia a TUI (Interface de Terminal) para monitoramento.

🖥️ Interface de Terminal (TUI)

A Forge CLI incluirá uma interface baseada em ratatui que permite visualizar:

  • Metabolismo do nó: Gráficos de CPU, memória e tokens de backpressure.
  • Vizinhança Causal: Mapa de peers e latência causal.
  • Landauer Ledger: Débitos e créditos energéticos em tempo real.

🔌 Flashing de Embarcados

Uma das funções críticas da Forge CLI é a preparação de MuleNodes. Através do comando flash, a ferramenta:

  1. Detecta o hardware conectado (via USB/Serial).
  2. Compila (se necessário) o firmware paebiru-hal para o alvo.
  3. Grava o firmware e configura a identidade inicial no dispositivo.

⏭️ Próximos passos

Após entender as ferramentas de gestão, você está pronto para escrever seu Primeiro plasmídeo.

🌐 Olá, malha

Agora que você tem o ambiente configurado, vamos subir seu primeiro nó e conectá-lo à malha do PAEBIRU.


🚀 Subindo o nó

Para rodar o nó padrão (paebiru-node), utilize o Cargo. O nó iniciará os subsistemas de rede (libp2p), o Kernel (loop GALS) e a API de observabilidade.

cargo run -p paebiru-node

O que esperar na saída

Você verá logs estruturados indicando a inicialização:

NODE  Iniciando PAEBIRU Node (Trilha de Aço)...
NODE  Ponta-a-ponta rodando. Aguardando descoberta de peers...
API   Servidor HTTP rodando em http://127.0.0.1:1975

✅ Verificando a saúde do nó

Em outro terminal, você pode verificar se o nó está respondendo corretamente através do endpoint de saúde:

curl http://localhost:1975/healthz

Saída esperada: OK


📡 Descobrindo a malha

A descoberta opera em duas camadas:

  • mDNS (local) — plug-and-play em LAN, sem configuração. Outros nós na mesma rede local são descobertos automaticamente.
  • Kademlia DHT (global) — descoberta na malha pública. Configurável via PAEBIRU_BOOTNODES. Sem bootnodes, o nó opera em Island Mode e só descobre pares via mDNS.

Quando peers são descobertos (por qualquer das camadas), o nó se conecta via gossipsub ao tópico paebiru-metabolism e começa a trocar mensagens de PulseRequest e PulseResponse. Veja a entrada “Pulse” no Dicionário canônico para a definição completa.

Configuração de bootnodes

A variável de ambiente PAEBIRU_BOOTNODES aceita uma lista CSV de multiaddrs libp2p:

export PAEBIRU_BOOTNODES="/ip4/1.2.3.4/tcp/4001/p2p/12D3KooWPj...,/ip4/5.6.7.8/tcp/4001/p2p/12D3KooWQ..."
cargo run -p paebiru-node

Multiaddrs inválidos são descartados com warn! (o nó segue operando em modo degradado com os bootnodes válidos).

Você verá logs como:

KERNEL  Mensagem recebida de 7f3a1b2c: PulseRequest { timestamp: ... }
KERNEL  Enviando PulseResponse para 7f3a1b2c
NETWORK  Kademlia: nova rota para 12D3KooW... (1 addr(s))
NETWORK  Kademlia bootstrap OK — routing table populada

🛠️ Comandos úteis

AçãoComando
Ver métricas (Prometheus)curl http://localhost:1975/metrics
Ver estado do nó via CLIpaebiru node status
Parar o nóCtrl + C (faz o shutdown gracioso)

⏭️ Próximos passos

Com o nó rodando, você pode explorar a Forge CLI para gerenciar sua identidade e interagir com a malha de forma mais avançada.

🔧 Caderno do Operador

Você é operador(a) de campo — implantou um nó, configurou o TPM, montou o armário de telecom, e o pager tocou às 3h da manhã. Esta página é o seu manual de bolso. Para o manual de cada incidente, veja os Runbooks.

Princípios

  1. Nada se reza — tudo se mede. Antes de agir, leia o estado real do nó (/healthz, /metrics, logs estruturados).
  2. Backpressure é mensagem, não erro. Se o LandauerLedger está vermelho, o sistema está te avisando — não force mais carga.
  3. Receptor-reator. Cada ação sua é um ato metabólico na malha: emite um receipt. Se o receipt não voltar, refaça.
  4. Mude a membrana, não o core. A maioria dos incidentes se resolve trocando adaptadores, não lógica de domínio.

Ferramentas essenciais

FerramentaO que dáComando típico
paebiru-cli (paebiru)Inspeção e operação localpaebiru node status
curl http://localhost:1975/healthzLiveness/readiness200 OK = OK
curl http://localhost:1975/metricsPrometheus endpointscrape por Prometheus
journalctl -u paebiru-node -fLogs do serviço systemdtail -f
PAEBIRU_API_PORTTrocar porta da APIsetar em /etc/paebiru.env
PAEBIRU_STORAGE_PATHDiretório de persistênciadefault ~/.paebiru

Áreas de runbook

Antes de pedir ajuda

Reúna:

  1. Versão (paebiru --version).
  2. PAEBIRU_STORAGE_PATH (anonimizado!).
  3. Saída de paebiru node status.
  4. Últimos 200 linhas de log do serviço.
  5. Hash do commit (git rev-parse HEAD).
  6. O que você mudou desde a última operação bem-sucedida.

Padrão de comunicação: abra uma issue com a tag operator-help e inclua o acima. Não cole segredos — apenas identificadores públicos de identidade (Peer ID em hex, não a chave privada).

Variáveis de ambiente canônicas

VariávelDefaultNunca em produção
PAEBIRU_SKIP_PFfalsetrue (desabilita Portão 1)
PAEBIRU_SKIP_TRACERfalsetrue (desabilita OTel)
PAEBIRU_SKIP_GEO_DISCOVERYfalsetrue em produção
PAEBIRU_SKIP_GPU_TESTSfalseirrelevante em prod

Regra de ferro: qualquer PAEBIRU_SKIP_* ligado em produção é veto algedônico — o nó se autodesliga após o alarme.

🔌 Flashing Embarcado

Guia para preparar e gravar o firmware PAEBIRU em dispositivos microcontrolados (MuleNodes).


1. Preparação do Toolchain

Certifique-se de ter os alvos Rust instalados:

rustup target add riscv32imc-unknown-none-elf thumbv7em-none-eabihf

Ferramentas de Gravação

  • ESP32: espflash ou esptool.py.
  • ARM (STM32/nRF52): probe-rs ou st-link.
  • AVR: avrdude.

2. Compilando o Firmware

Navegue até o diretório do seu dispositivo ou use o paebiru-hal:

cargo build -p paebiru-hal --target <target-do-seu-hardware> --release

3. Realizando o Flash

Utilize a Forge CLI para automatizar o processo (recomendado):

paebiru flash --chip esp32s3 --port /dev/ttyUSB0

Ou manualmente via probe-rs:

probe-rs run --chip STM32F401RETx target/<target>/release/paebiru-hal

4. Configuração de Identidade Inicial

Após o flash, o dispositivo estará em modo de Provisionamento.

  1. Conecte-se via Serial (115200 baud).
  2. O dispositivo gerará um par de chaves inicial e exibirá o PeerID.
  3. Utilize a CLI no seu computador para autorizar o novo nó na sua LocalSyncDomain.

5. Veja também

📊 Observabilidade

O PAEBIRU fornece visibilidade total sobre o metabolismo dos nós e a saúde da malha através de padrões abertos.


1. Stack Recomendada

  • Métricas: Prometheus (porta 1975 /metrics).
  • Tracing: Jaeger (porta 4317 OTLP).
  • Logs: Grafana Loki (logs JSON estruturados).
  • Visualização: Dashboards Grafana (veja o diretório ops/grafana/).

2. Métricas Críticas

MétricaSignificado
paebiru_metabolic_tokensDisponibilidade de backpressure.
paebiru_causal_maturity_driftDiferença temporal para a malha.
paebiru_security_gate_dropsPacotes bloqueados por portão.
paebiru_energy_micro_joules_totalGasto acumulado no LandauerLedger.

3. Distributed Tracing

Utilize o TraceID presente nos cabeçalhos das mensagens para rastrear o caminho de um plasmídeo através de múltiplos nós na malha global.

🔍 Troubleshooting

Guia rápido de sintomas e soluções para incidentes comuns.


Tabela de Sintomas

SintomaCausa ProvávelSolução
Connection resetFirewall ou MTU incompatível.Verifique regras XDP (R007).
Identity not foundTPM não inicializado ou path inválido.Verifique permissões (R002).
Drift detectedFalta de tráfego ou partição de rede.Force um pulso manual (R008).
Gas exhaustedSaldo insuficiente no LandauerLedger.Contribua com PoW ou aguarde crédito.

Logs Úteis

Procure por estas keywords nos logs:

  • CRITICAL: Veto Algedônico iminente.
  • SECURITY: Violação em algum dos 5 portões.
  • RECOVERY: Reconstrução do estado causal em curso.

📜 Postmortems

Lista de incidentes históricos e o que aprendemos com eles para evoluir os Runbooks.


Histórico de Incidentes

(Esta seção será preenchida conforme a malha evolui)

[2026-06-01] Tempestade de Sincronização

  • Sintoma: CPU em 100% em nós de borda durante reconexão após queda de WAN regional.
  • Causa: Backpressure ausente no estágio de Correnteza.
  • Correção: Implementado token bucket no sync da Pororoca Causal (RFC 019).
  • Runbook Atualizado: R009 · Migração.

📋 R001 · Boot de nó em campo

Sintoma: O serviço paebiru-node não inicia, falha imediatamente após o boot ou entra em um loop de reinicialização.

flowchart LR
    S[paebiru-node não sobe<br/>ou reinicia em loop] --> D[Diagnóstico<br/>journalctl + cargo run + ss :1975]
    D -- Porta 1975 ocupada --> A1[Ação 1<br/>matar processo ou<br/>export PAEBIRU_API_PORT]
    D -- Storage sem perms --> A2[Ação 2<br/>mkdir + chmod 700<br/>~/.paebiru]
    D -- Falta de entropia<br/>pqcrypto panics --> A3[Ação 3<br/>instalar/configurar<br/>haveged]
    A1 --> V[Verifica<br/>curl :1975/healthz<br/>log: Ponta-a-ponta rodando]
    A2 --> V
    A3 --> V
    V -- OK --> End[Encerrar]
    V -- não resolveu --> Esc[Escalar<br/>issue operator-help]

🔍 Diagnóstico

  1. Verifique os logs do sistema:
    journalctl -u paebiru-node -n 100 -f
    
  2. Tente um início manual para ver a saída direta:
    cargo run -p paebiru-node
    
  3. Verifique se a porta da API (1975) já está ocupada:
    ss -tulpn | grep 1975
    

🛠️ Ação

Causa 1: Porta Ocupada

Se a porta 1975 estiver em uso por outro processo:

  • Ação: Mate o processo anterior ou altere a porta via variável de ambiente:
    export PAEBIRU_API_PORT=1976
    

Causa 2: Caminho de Armazenamento Inválido

Se o log indicar erro ao abrir o banco de dados ou identidade:

  • Ação: Verifique as permissões de PAEBIRU_STORAGE_PATH (padrão ~/.paebiru):
    mkdir -p ~/.paebiru
    chmod 700 ~/.paebiru
    

Causa 3: Pânico de PQC (Criptografia)

Se o log mostrar erro em pqcrypto ou falta de entropia:

  • Ação: Verifique se o sistema tem haveged ou similar para garantir entropia suficiente no /dev/random.

✅ Verificação

  1. O comando curl http://localhost:1975/healthz retorna OK.
  2. O log mostra: NODE Ponta-a-ponta rodando. Aguardando descoberta de peers....

🚨 Escalar

Se o nó continuar falhando após as ações acima, colete a saída de paebiru node status (se disponível) e abra uma issue com a tag operator-help.

📋 R002 · Identidade TPM

Sintoma: O nó falha ao carregar ou gerar a identidade soberana. Logs mostram erros como TPM Error, Permission denied on /dev/tpm0 ou Identity not found.


🔍 Diagnóstico

  1. Verifique a existência do dispositivo TPM:
    ls -l /dev/tpm*
    
  2. Verifique se o usuário tem permissão:
    groups $USER | grep tss
    
  3. Teste as capacidades do TPM:
    tpm2_getcap properties-fixed | head -n 20
    

🛠️ Ação

Causa 1: Permissão Negada

Se /dev/tpm0 existir mas o acesso for negado:

  • Ação: Adicione o usuário ao grupo tss (ou o grupo dono do device) e reinicie a sessão:
    sudo usermod -aG tss $USER
    

Causa 2: TPM Bloqueado (Dictionary Attack Lockout)

Se o TPM estiver em modo de bloqueio por muitas tentativas falhas:

  • Ação: Aguarde o tempo de lockout ou, se tiver a senha de owner, faça o reset:
    tpm2_dictionarylockout --clear-lockout
    

Causa 3: Falta de suporte a PQC no TPM

Se o nó exige ML-DSA mas o TPM é antigo:

  • Ação: O PAEBIRU tentará um fallback para armazenamento seguro via software se PAEBIRU_ALLOW_SW_IDENTITY=true estiver setado (não recomendado para produção).

✅ Verificação

  1. Execute paebiru identity status.
  2. O log deve mostrar: SECURITY Identidade carregada via HardwarePassport (TPM 2.0).

🚨 Escalar

Se o erro persistir, verifique a versão do firmware do TPM e consulte a RFC 007 sobre Identidade Soberana.

📋 R003 · Rotação de chaves FROST

Sintoma: Alerta de “Key Age Exceeded” ou perda de um ou mais shares de uma chave distribuída (threshold signature). O nó pode perder a capacidade de assinar transações se cair abaixo do threshold (ex: 3 de 5).


🔍 Diagnóstico

  1. Verifique o estado das shares locais:
    paebiru identity check-shares
    
  2. Verifique a conectividade com os outros guardiões:
    paebiru node peers | grep guardian
    

🛠️ Ação

Causa 1: Share Perdida ou Corrompida

Se uma share local foi deletada ou o hardware falhou:

  • Ação: Inicie o protocolo de recuperação de share (DPSS) com o quorum restante. Você precisará de $t$ guardiões online.
    paebiru identity recover-share --threshold 3
    

Causa 2: Rotação Preventiva (Idade da Chave)

A política de segurança exige rotação a cada 90 dias.

  • Ação: Inicie uma nova cerimônia FROST. O sistema gerará novos polinômios e distribuirá novas shares sem mudar a chave pública agregada (se usar resharing) ou gerando uma nova (se for migração total).
    paebiru identity rotate --ceremony-id <UUID>
    

✅ Verificação

  1. paebiru identity status mostra “Shares: Healthy (3/5)”.
  2. O próximo recibo gerado é assinado com sucesso.

🚨 Escalar

Se o quorum mínimo não for atingido, a chave está permanentemente perdida. Acione o Plano de Recuperação de Desastre (R011).

📋 R004 · Recuperação de ledger

Sintoma: Erros de I/O no C.A.P.I.B.A., falha na verificação de checksum de blocos, ou divergência causal (fork local). Logs mostram Corrupted block ou Hash mismatch.


🔍 Diagnóstico

  1. Verifique a integridade do banco local:
    paebiru capiba check --full
    
  2. Verifique se há espaço em disco:
    df -h $PAEBIRU_STORAGE_PATH
    
  3. Identifique o último bloco válido:
    paebiru capiba last-valid
    

🛠️ Ação

Causa 1: Corrupção de Índice (Prolly Tree)

Se os dados estão lá, mas a árvore de busca está quebrada:

  • Ação: Reconstrua os índices a partir dos blocos brutos (WAL).
    paebiru capiba rebuild-index
    

Causa 2: Blocos Faltantes ou Divergentes

Se o nó perdeu mensagens durante uma partição longa:

  • Ação: Force uma ressincronização (Pororoca Causal) com um peer de confiança:
    paebiru capiba sync --peer <TrustedPeerID>
    

Causa 3: Falha de Hardware (Bad sectors)

  • Ação: Mova o storage para um novo disco e restaure a partir do peer mais próximo ou do backup em Oceano.

✅ Verificação

  1. paebiru capiba check retorna “Integrity OK”.
  2. O nó volta a processar novos recibos normalmente.

🚨 Escalar

Em caso de divergência massiva de estado entre muitos nós, acione a governança econômica para um snapshot de consenso.

📋 R005 · Quarentena MacrophageVM

Sintoma: Logs do Kernel mostram SECURITY Package quarantined ou MacrophageVM: Antibody synthesized. O nó detectou uma mensagem suspeita e a isolou para análise.


🔍 Diagnóstico

  1. Verifique o ID do pacote isolado:
    paebiru security quarantine-list
    
  2. Inspecione o relatório de comportamento da VM:
    paebiru security report <PackageID>
    

🛠️ Ação

Causa 1: Falso Positivo (Plasmídeo Conhecido)

Se você confia na fonte e a VM foi muito conservadora:

  • Ação: Libere o pacote manualmente e adicione a assinatura à lista de permissões local.
    paebiru security release <PackageID> --force
    

Causa 2: Ataque de Comportamento (Esgotamento de Memória)

Se o relatório indica que o pacote tentou alocar memória excessiva dentro da sandbox:

  • Ação: O sistema gerará um Anticorpo automaticamente. Garanta que ele foi propagado:
    paebiru security broadcast-antibody <PackageID>
    

Causa 3: Divergência de Contrato (CDDL)

Se o pacote violou o esquema de dados do Portão 5:

  • Ação: Rejeite permanentemente e notifique o emissor (se for um peer conhecido).

✅ Verificação

  1. paebiru security status mostra “Quarantine: Empty”.
  2. O rastro do anticorpo aparece nos logs do GossipSub.

🚨 Escalar

Se houver uma onda massiva de quarentenas de fontes diferentes, o nó pode estar sofrendo um ataque de dia zero coordenado. Acione o canal de segurança global.

📋 R006 · Atualização OTA

Sintoma: Nova versão de firmware disponível. O nó precisa ser atualizado remotamente (Over-The-Air) sem perda de identidade soberana ou estado causal.


🔍 Diagnóstico

  1. Verifique a versão atual:
    paebiru --version
    
  2. Verifique o status do binário de atualização:
    paebiru update check
    

🛠️ Ação

Causa 1: Atualização Menor (Patch)

  • Ação: Execute a atualização automática. O nó fará o download, validará a assinatura ML-DSA do binário e reiniciará.
    paebiru update apply --version <Version>
    

Causa 2: Atualização de Kernel (Breaking Change)

Se a atualização altera o formato do DVV ou do banco de dados:

  • Ação: Realize um snapshot do C.A.P.I.B.A. antes de prosseguir.
    paebiru capiba snapshot --path /mnt/backup/
    paebiru update apply --rebuild-index
    

✅ Verificação

  1. O nó sobe e paebiru --version mostra a nova versão.
  2. paebiru node status indica que os peers estão sendo redescobertos.

🚨 Escalar

Se o nó entrar em loop de boot após a atualização, utilize a ferramenta de Flash físico (R001) para reverter para a versão anterior preservando a partição de storage.

📋 R007 · Saturação XDP

Sintoma: O Portão 1 (Load Shedder) está descartando uma alta porcentagem de pacotes. Logs mostram XDP: Dropping packets due to rate limit ou Saturação do Portão 1.


🔍 Diagnóstico

  1. Verifique a taxa de descarte:
    paebiru security metrics | grep xdp_drop_rate
    
  2. Identifique a fonte do tráfego volumétrico:
    paebiru security top-talkers --gate 1
    

🛠️ Ação

Causa 1: Ataque DDoS Volumétrico

  • Ação: Aumente a agressividade do rate limiting no kernel eBPF e bloqueie os IPs/PeerIDs agressores no Bloom Filter.
    paebiru security block-peer <AttackerID> --permanent
    

Causa 2: Erro de Configuração de Malha

Muitos peers tentando sincronizar simultaneamente.

  • Ação: Ajuste os tokens de backpressure para suavizar a ingestão.
    export PAEBIRU_MAX_TOKENS=50
    

✅ Verificação

  1. A taxa de descarte (drop rate) estabiliza abaixo de 5%.
  2. A CPU do sistema (processamento eBPF) retorna a níveis saudáveis.

🚨 Escalar

Se a saturação ocorrer a nível de placa de rede (NIC) impedindo o acesso SSH/gerência, o nó deve ser isolado fisicamente do switch para limpeza de regras.

📋 R008 · Drift de relógio Langevin

Sintoma: O nó não consegue validar recibos de peers devido a “Causal Maturity Future Drift”. O tempo de Langevin do nó local está muito atrás ou muito à frente da vizinhança.


🔍 Diagnóstico

  1. Compare o tick local com o tick da malha:
    paebiru entropy status
    
  2. Verifique a variação entrópica (ΔS):
    paebiru entropy metrics
    

🛠️ Ação

Causa 1: Falta de Atividade Metabólica

O nó está “congelado” porque não processa eventos.

  • Ação: Force um TriggerPulse para re-sincronizar o estado metabólico.
    paebiru node pulse --force
    

Causa 2: Partição de Rede Longa

O nó operou em “Ilha” por muito tempo.

  • Ação: Inicie uma Pororoca Causal para puxar a maturidade dos vizinhos dominantes.
    paebiru capiba sync --strategy dominant-causal
    

✅ Verificação

  1. paebiru entropy status mostra “Sync Status: Converged”.
  2. Novos recibos são aceitos sem erros de maturidade.

🚨 Escalar

Se o drift for causado por falha no gerador de ruído gaussiano (falta de entropia de hardware), o nó deve ser reiniciado com drivers de entropia corrigidos.

📋 R009 · Migração para Oceano

Sintoma: O storage quente/morno (Nascente/Correnteza) está atingindo o limite de capacidade. O nó precisa mover dados antigos para o Tier frio (Oceano).


🔍 Diagnóstico

  1. Verifique o uso de disco por estágio:
    paebiru capiba usage
    
  2. Verifique a maturidade causal dos dados:
    paebiru capiba status --tier morna
    

🛠️ Ação

Causa 1: MUS (Minimum Useful Survival) Atingido

Dados excederam o tempo de vida útil garantido na memória quente.

  • Ação: Dispare o processo de transmutação analítica para Parquet/Iceberg.
    paebiru capiba migrate --to oceano
    

Causa 2: Saturação de Disco Imediata

  • Ação: Force a migração agressiva, priorizando dados com $\Delta C \to 0$ (baixa interação).
    paebiru capiba migrate --aggressive --min-interact 0
    

✅ Verificação

  1. Espaço em disco na partição quente é liberado.
  2. Os metadados dos blocos migrados aparecem no IcebergManifest.

🚨 Escalar

Se a migração para o Oceano (armazenamento externo/Filecoin) falhar, o nó ativará a Apoptose Saudável, deletando dados irrelevantes para preservar a Homeostasia do sistema.

📋 R010 · Falha de ZK-PoL

Sintoma: O nó não consegue gerar ou validar Provas de Localização (Portão 4). Mensagens são rejeitadas com erro ZK-PoL verification failed.


🔍 Diagnóstico

  1. Verifique o backend de ZK:
    paebiru security status --gate 4
    
  2. Teste a geração de prova simples:
    paebiru security test-pol
    

🛠️ Ação

Causa 1: Falta de Proximidade Geográfica

O nó está tentando assinar uma localização fora do raio permitido pelo contrato.

  • Ação: Verifique se as coordenadas de referência (centros de quórum) estão atualizadas.

Causa 2: Erro de Setup Confiável (CRS)

Os parâmetros Groth16 local estão corrompidos.

  • Ação: Baixe novamente o setup confiável oficial da malha.
    paebiru security refresh-crs
    

✅ Verificação

  1. O comando paebiru security test-pol retorna “Proof valid”.
  2. O nó volta a participar de rounds de aprendizado federado que exigem PoL.

🚨 Escalar

Falhas sistemáticas de ZK-PoL em múltiplos nós podem indicar um ataque de eclipse ou uma mudança não documentada no circuito do protocolo. Consulte a equipe de criptografia.

📋 R011 · Disaster Recovery

Sintoma: Falha catastrófica de hardware, perda total de dados locais ou roubo do dispositivo físico.


🛠️ Ação

Passo 1: Revogação de Identidade

Se o dispositivo foi roubado ou a chave comprometida:

  • Ação: Use sua chave de backup (ou quorum FROST) para anunciar a revogação do PeerID na malha.
    paebiru identity revoke <OldPeerID> --reason compromised
    

Passo 2: Provisionamento de Novo Hardware

  • Ação: Instale o OS, as dependências de sistema (R001) e o PAEBIRU Node.

Passo 3: Restauração de Identidade

  • Ação: Importe seu HardwarePassport ou regenere as shares FROST a partir dos guardiões (R003).

Passo 4: Reconstrução do Estado Causal

  • Ação: Puxe o histórico completo do Oceano e sincronize as últimas janelas Langevin com os vizinhos mais próximos.
    paebiru capiba restore --from-ocean
    paebiru node sync-all
    

✅ Verificação

  1. O novo nó é reconhecido pela malha como o sucessor legítimo do nó anterior.
  2. O LandauerLedger reflete o saldo histórico restaurado.

🚨 Escalar

Caso as chaves de backup e o quorum FROST também sejam perdidos, a soberania sobre aquela identidade é irrecuperável. Um novo PeerID deve ser gerado do zero.

🔬 Processo RSE — Research, Strategy, Execution

O ciclo RSE é o fluxo obrigatório de contribuição. Ele é simples, escasso em formalidade, e não pula para código. Agentes de IA que trabalham no PAEBIRU devem segui-lo: a skill paebiru-developer operacionaliza o ciclo inteiro.

flowchart LR
    A[Issue /<br/>necessidade] --> R[Research<br/>O que existe?]
    R -->|gaps| S[Strategy<br/>Onde colocar?]
    S -->|plano| E[Execution<br/>Cirurgia + testes]
    E -->|falhou| R
    E -->|passou| P[PR +<br/>checklist]
    P --> M[Maintainer<br/>merge]
    M -->|regressão| R

1. Research

Pergunta-guia: “O que já existe, o que falta, e quem tentou isso antes?”

Atividades:

  1. Cite a fonte do problema. Issue? Runbook? RFC em DRAFT/PROPOSED? Bug? Postmortem? Sem fonte, a tarefa não é contribuição — é feature creep.
  2. Mapeie os Bounded Contexts afetados. Para cada um, abra a BC doc correspondente em architecture/bounded-contexts/. Se não existir, a tarefa é primeiro escrever a BC doc.
  3. Verifique o Dicionário canônico reference/dictionary.md para termos relevantes. Se um termo não estiver, adicione-o antes de propor código.
  4. Leia a skill relevante em .agents/skills/ — ou paebiru-architect se for transversal.
  5. Procure RFCs em formalização em rfc/README.md. Se a sua mudança intersecta um tópico, escreva a RFC primeiro ou espere a ratificação daquela.

Saída esperada: parágrafo de 5-10 linhas na descrição da issue ou do PR, respondendo:

  • Qual problema está sendo resolvido?
  • Quais BCs são afetados?
  • Quais dogmas estão em jogo (4 Dogmas)?
  • Quais termos do Dicionário precisam ser revisados/criados?
  • Quais RFCs estão relacionadas ou em formalização?

2. Strategy

Pergunta-guia: “Onde colocar a mudança sem costurar contextos?”

Atividades:

  1. Escolha a membrana certa. Se a mudança cruza dois BCs, você provavelmente está costurando — volte à fase 1 e reestruture. Em caso de dúvida, abra uma issue com a tag architect-help antes de prosseguir.
  2. Defina a interface (port) antes da implementação. Traits em crates/<bc>/src/ports/ são a fronteira. Se a interface pública muda, é RFC obrigatória (ver §7 do CONTRIBUTING).
  3. Liste os testes que vão cobrir a mudança. Mínimo:
    • 1 teste unitário por novo tipo/função pública;
    • 1 teste de integração se tocar actor/ ou adaptadores;
    • 1 teste property-based se tocar invariante (DVV, soma zero, Landauer, etc.);
    • 1 teste no_std se tocar Kernel/Math.
  4. Identifique o gate de qualidade (ver quality.md):
    • Conformidade (lint, fmt, audit)?
    • GALS & Domínio (test, cobertura)?
    • Verificação formal (TLA+/Lean 4)?
    • Embarcada (no_std build)?
  5. Documente o que pode dar errado. Liste 2-3 cenários de regressão e como o teste pega cada um.

Saída esperada: parágrafo de 5-10 linhas descrevendo:

  • Em que BC/crate a mudança entra.
  • Qual a nova interface (se houver).
  • Lista de testes a serem escritos.
  • Gate de qualidade aplicável.
  • Riscos e mitigações.

3. Execution

Pergunta-guia: “Como implementar de forma cirúrgica e validável?”

Atividades:

  1. Branches pequenos. Um branch por unidade lógica: feat/<bc>-<unidade>, fix/<bc>-<sintoma>, docs/<escopo>, rfc/<número>-<slug>.
  2. Commits atômicos. Um commit por mudança conceitual. Mensagem em imperativo, assunto ≤ 72 chars, corpo que responde por quê (não o quê).
  3. Validação local antes do push:
    make check         # tipos
    make lint          # clippy + fmt --check
    make test          # suíte
    make coverage      # ≥ 90 % de linhas
    make pre-commit    # hooks locais
    
  4. Atualize o que mudou fora do código:
    • BC doc se a API pública mudou.
    • Dicionário se um termo novo entrou em uso.
    • Runbook se a mudança afeta operação.
    • CHANGELOG.md na seção Unreleased (categoria: Added/Changed/Fixed/Security/Removed).
  5. PR com checklist completo. Use o template. Preencha:
    • Ciclo RSE (1-2 linhas cada).
    • 4 Dogmas preservados (declaração explícita).
    • Cobertura antes/depois.
    • RFCs citadas (se aplicável).
    • Atribuição correta (DCO Signed-off-by).

Saída esperada: PR aberto com CI verde, revisores marcados, descrição completa.


4. Review & Merge

Quem revisa: 1 mantenedor + 1 peer do BC afetado. Quem aprova: mantenedor com permissão de merge. Merge strategy: squash and merge por padrão, rebase and merge para séries de 1-3 commits coesos.

Checklist do reviewer:

  • Código lê como a prosa do BC doc.
  • Não há costura entre BCs.
  • Não há Mutex/Arc<Mutex<>> cruzando fronteira.
  • Não há std::time::Instant no domínio.
  • Não há bloqueio dentro de loops de ator.
  • Não há novos warnings de cargo clippy.
  • Cobertura mantida (≥ 90 %).
  • BC doc / Dicionário / CHANGELOG atualizados.

5. Anti-padrões de processo

❌ Anti-padrão✅ Correção
“Vou só commitar isso rapidinho” sem RFCAbra issue → estratégia → execute
“Vou refatorar a BC vizinha pra ficar consistente”Refatore em PR separado, antes ou depois
“Vou adicionar essa dependência que resolve tudo”Avalie o Lockfile, o footprint no_std, e a licença
“Vou pular o pre-commit, o CI pega”CI não substitui pre-commit — corra local
“Vou usar IA para gerar o commit message inteiro”IA pode sugerir, você valida e assina
“Vou só atualizar a doc do BC, sem mexer no código”Ótimo — mas como PR separado, com peer de docs

6. Veja também

🛡️ Qualidade — 4 Dogmas + 4 Esteiras

A Muralha da Qualidade do PAEBIRU tem 4 dogmas (o que é inegociável) e 4 esteiras (como o gate é executado em CI). Nenhuma regressão chega a main sem passar por todas as 4.

flowchart TB
    A[PR aberto] --> E1[Esteira 1<br/>Conformidade]
    E1 -->|passa| E2[Esteira 2<br/>GALS & Domínio]
    E2 -->|passa| E3[Esteira 3<br/>Verificação Formal]
    E3 -->|passa| E4[Esteira 4<br/>Embarcada]
    E4 -->|passa| M[main]
    E1 -->|falha| X[bloqueado]
    E2 -->|falha| X
    E3 -->|falha| X
    E4 -->|falha| X

Os 4 Dogmas Inquebráveis

Originais do AGENTS.md §4, ratificados como princípio de revisão. Um PR que viola qualquer dogma é rejeitado mesmo que funcione.

🛡️ Dogma 1 — Isolamento Absoluto (Hexagonal)

“A lógica de domínio é o núcleo sagrado. Infraestrutura é detalhe injetado via traits.”

Invariantes:

  • crates/<bc>/src/domain/ não importa de actor/, ports/ ou adapters/. Verificado por:
    grep -rE '^use crate::(actor|ports|adapters)' crates/<bc>/src/domain/
    # deve retornar vazio
    
  • Toda dependência de I/O passa por trait declarado em crates/<bc>/src/ports/.
  • Cruzamento entre BCs é via artefato imutável com receipt — nunca Arc<Mutex<T>> compartilhado.

Sinais de violação:

  • use std::net, use std::fs, use std::time::Instant em domain/.
  • tokio::spawn ou mpsc::channel em domain/.
  • Estruturas do BC A importadas diretamente em BC B.

🌀 Dogma 2 — Paradigma GALS & Ator

“Localmente síncrono, globalmente assíncrono. Nunca bloqueie dentro do loop do ator.”

Invariantes:

  • Loops de ator usam apenas mpsc::Receiver::recv().await, tokio::select! ou similar. Nenhuma espera bloqueante.
  • Estado mutável do ator é dentro do struct do ator; nada de Mutex<DomainState>.
  • Mensagens entre BCs são serializáveis (Serialize + Deserialize).

Sinais de violação:

  • std::sync::Mutex, std::sync::RwLock no domínio ou no ator.
  • thread::sleep, std::thread::join em código de runtime.
  • Operações de I/O síncronas (std::fs::read, std::net::TcpStream) sem wrapper async.

⚙️ Dogma 3 — no_std First

“O código de domínio deve compilar sem a biblioteca padrão, do ATmega ao mainframe.”

Invariantes:

  • crates/kernel/src/domain/ compila para riscv32imc-unknown-none-elf e thumbv7em-none-eabihf sem warnings.
  • crates/math/ compila para os mesmos alvos.
  • Coleções dinâmicas usam heapless em vez de Vec/HashMap no caminho embarcado.

Sinais de violação:

  • use std::collections::* em código domain/.
  • Alocação dinâmica (Box, Vec, String) em código no_std.
  • Dependências que exigem std automaticamente.

🔌 Dogma 4 — Interoperabilidade Blindada (Opaque Handles & Zero-Copy)

“O FFI expõe apenas ponteiros opacos. Serialização pesada é substituída por vistas diretas da memória.”

Invariantes:

  • Tipos públicos do crate expostos a FFI usam #[repr(C)] + ponteiro opaco (sem campos públicos).
  • Buffers compartilhados via FFI são zero-copy (ponteiro + tamanho).
  • serde_json/protobuf proibidos em crates/bindings/* para caminhos quentes.

Sinais de violação:

  • Tipos Rust complexos visíveis no header C.
  • serde_json::from_str em hot path de binding.
  • Vec<T> retornado através de fronteira FFI (vira cópia).

As 4 Esteiras da Muralha

Cada esteira tem um critério de saída binário (passa/falha). CI enforça em ordem. Uma esteira só é avaliada se a anterior passou.

Esteira 1 — Conformidade (sintática, estática, segurança básica)

Ferramentas:

FerramentaO que verificaBloqueia?
cargo fmt --all -- --checkFormatação canônicaSim
cargo clippy --all -- -D warningsLints oficiaisSim
cargo auditCVEs em dependênciasSim (HIGH/CRITICAL)
cargo vetSupply chain (lockfile de imports)Sim
rtk make lint (via rtk proxy)Igual a make lint mas rápidoSim
pre-commit (.pre-commit-config.yaml)Whitespace, EOF, YAML, TOMLSim

Saída da esteira: zero erros, zero warnings de clippy, zero CVEs HIGH/CRITICAL.

Esteira 2 — GALS & Domínio (testes + cobertura)

Ferramentas:

FerramentaO que verificaBloqueia?
cargo test --allSuíte unitária + integraçãoSim
cargo test --docDoctestsSim
cargo llvm-cov --all --fail-under-lines 90Cobertura de linhas ≥ 90 %Sim
proptest (em crates relevantes)Invariantes por property-basedSim em Kernel/crypto/economia
cargo test --test local_node_integrationCiclo de vida ponta-a-pontaSim

Saída da esteira: suíte verde, cobertura ≥ 90 %, sem teste flaky.

Esteira 3 — Verificação Formal (TLA+ + Lean 4)

Verificação cirúrgica: aplicada só onde a garantia supera o custo de modelagem. Detalhes em formal-verification.md.

Ferramentas:

FerramentaOndeO que prova
TLA+crates/*/formal/tla/Concorrência, GALS liveness, soma zero de crédito, soundness de ZK-PoL
Lean 4crates/paebiru-math/formal/lean/ e formal/lean/Pureza algorítmica: Haversine, Reed-Solomon, Ising, Langevin, MutualCredit
make verify-formalorquestradorRoda tudo; pula Lean 4 se lake ausente

Saída da esteira: modelos compilam, provas não regrediram, contradições detectadas resolvidas.

Esteira 4 — Embarcada (no_std)

Ferramentas:

AlvoComandoAplicável a
riscv32imc-unknown-none-elfcargo check --target riscv32imc-unknown-none-elfKernel, Math, HAL
thumbv7em-none-eabihfcargo check --target thumbv7em-none-eabihfKernel, Math, HAL
wasm32-unknown-unknowncargo check --target wasm32-unknown-unknown --no-default-featuresPlasmids, Kernel (subset)

Saída da esteira: build limpo para todos os alvos embarcados suportados pela mudança.


Tabela de mapeamento: dogma × esteira

DogmaEsteira 1 (Conform.)Esteira 2 (GALS)Esteira 3 (Formal)Esteira 4 (Embarcada)
1. Hexagonalclippy lints sobre importsTestes de porta mockadaTLA+ sobre membranano_std build
2. GALS & AtorLints clippy::async_yields_asyncTeste do loop do atorTLA+ livenessno_std + heapless
3. no_stdcargo check --no-default-featuresSuíte no_std-onlyLean 4 sobre funções purasToda a esteira
4. Opaque FFIcargo clippy + revisão manualTestes de bindingCompila para wasm32

Como aplicar este documento

  • Autor do PR: percorra a tabela para o dogma que sua mudança toca. Cada dogma tem testes específicos em cada esteira.
  • Reviewer: use a tabela como checklist de revisão.
  • Agente de IA: leia a skill paebiru-architect antes de propor patches que tocam dogmas. Cite o dogma preservado no PR.

Veja também

🛡️ Verificação Formal

No PAEBIRU, a verificação formal não é um luxo acadêmico, mas uma ferramenta pragmática de engenharia. Utilizamos modelos formais para provar invariantes críticas de concorrência, economia e matemática.


1. Abordagem Pragmática

Não tentamos provar cada linha de código. Aplicamos a verificação cirurgicamente onde o custo da falha é alto ou o comportamento é complexo.

FerramentaUso PrincipalLocalização
TLA+Concorrência, loop GALS, liveness de atores, consenso bizantino.crates/*/formal/tla/
Lean 4Pureza algorítmica, precisão geodésica, conservação de energia.crates/*/formal/lean/

2. TLA+ (Temporal Logic of Actions)

Usado para modelar o estado global e a interação entre atores.

  • Exemplo: Provar que o loop do Kernel nunca entra em deadlock mesmo sob saturação de backpressure.
  • Execução: Através do TLC Model Checker.

3. Lean 4 (Prova de Teoremas)

Usado para garantir a correção de funções puras e fundamentação matemática.

  • Exemplo: Prova de que o Hamiltoniano de Ising converge para um estado de energia mínima sob as regras do scheduler.
  • Execução: Através do comando lake build no diretório formal.

4. Integração com o Fluxo RSE

Toda RFC que introduz um novo protocolo crítico (ex: um novo portão de segurança ou mecanismo de crédito) deve ser acompanhada de uma especificação formal mínima.

  1. Research: Identificar as propriedades de segurança e liveness.
  2. Strategy: Escrever o modelo TLA+ ou Lean.
  3. Execution: Implementar em Rust e validar contra o modelo.

5. Como rodar as verificações

Utilize o orquestrador canônico:

make verify-formal

Este comando invocará os checkers de TLA+ e os compiladores de Lean 4 configurados no workspace.


6. Veja também

🗺️ Mapeamento do Workspace

O PAEBIRU é um workspace Cargo extenso com mais de 30 membros. Este guia ajuda você a se localizar e entender a maturidade de cada componente.


1. Estrutura de Diretórios

paebiru/
├── apps/               # Aplicações finais (binários)
├── crates/             # Bounded Contexts e bibliotecas core
│   ├── bindings/       # Bindings para 13 linguagens (FFI)
├── docs/               # Documentação mdBook (esta que você lê)
├── simulations/        # Simulações hardware-in-the-loop (Python)
└── supply-chain/       # Auditorias e travas de dependências

2. Maturidade por Crate (Fase 1)

CrateBounded ContextEstadoResponsabilidade
paebiru-kernelKernel🟢 EstávelLoop GALS, Rede, Segurança
paebiru-node(App)🟢 EstávelDaemon principal do nó
paebiru-mathMatemática🟡 BetaIsing, Langevin, Reed-Solomon
paebiru-biologyBiologia🟠 AlfaABAPORU, SNN
paebiru-economyEconomia🟠 AlfaDRE, Barter, Joule
paebiru-capibaC.A.P.I.B.A.🟠 AlfaPersistência Causal
paebiru-halHAL🟠 Alfano_std, Drivers
paebiru-apiAPI🟠 AlfaHTTP, Metrics, Tracing

3. Fluxo de Dependências

Para preservar o Dogma 1 (Isolamento Hexagonal), seguimos uma hierarquia estrita:

  1. paebiru-math e paebiru-commons são a base (zero dependências internas).
  2. paebiru-kernel depende da base.
  3. Bounded Contexts de domínio (biology, economy, learn) dependem do kernel através de traits.
  4. paebiru-node orquestra tudo, injetando as implementações concretas.

4. Bindings de Linguagem

Os crates em crates/bindings/ são pontes FFI. Eles não devem conter lógica de domínio, apenas mapeamentos de tipos e chamadas para o core em Rust.


5. Veja também

📜 Escrevendo RFCs

Mudanças significativas na arquitetura, protocolos ou economia do PAEBIRU exigem uma RFC (Request for Comments). Este processo garante que as decisões sejam debatidas, documentadas e imutáveis após a ratificação.


1. Quando escrever uma RFC?

  • Adição de um novo Bounded Context (crate).
  • Mudança em uma interface pública de Port (trait em crates/*/ports/).
  • Alteração em protocolos de rede ou formatos de recibo.
  • Novas regras de governança ou incentivos econômicos.

2. O Processo (Fluxo Vital)

  1. Idea: Discuta a ideia em uma Issue ou Discussion com a tag rfc-proposal.
  2. Draft: Solicite um número (ex: RFC 054) e copie o template oficial.
  3. Proposed: Abra um PR com o status PROPOSED. O PR deve ficar aberto por pelo menos 14 dias para debate técnico.
  4. Standard: Se houver consenso, um mantenedor marca como STANDARD e faz o merge.

3. Template de RFC

Copie de .agents/skills/paebiru-rfc-writer/references/TEMPLATE.md. Seções obrigatórias:

  • Resumo: Um parágrafo para leigos.
  • Motivação: Por que agora? Qual o custo de não fazer?
  • Especificação Técnica: Detalhes granulares (structs, enums, sequências).
  • Impacto em BCs: Tabela de quais crates serão alterados.

4. Regras de Ouro

  • Numeração Imutável: Uma vez atribuído, o número da RFC nunca muda.
  • Supersedes: Se uma RFC nova substitui uma antiga, use o campo supersedes no cabeçalho.
  • Foco no Domínio: Evite detalhes de implementação (ex: “usar biblioteca X”) a menos que seja estritamente necessário para o protocolo.

5. Veja também

✍️ Escrevendo Documentação

A documentação do PAEBIRU é a “memória externa” do organismo. Ela deve ser tão rigorosa quanto o código, seguindo convenções estritas para garantir que seja útil tanto para humanos quanto para agentes de IA.


1. Onde Documentar?

  • Documentação Local: Comentários /// (RustDoc) no código. Explique o porquê, não o quê.
  • Documentação Transversal: Vive em docs/src/. Use para arquitetura, teoria, guias e runbooks.
  • README.md: Cada crate deve ter um README descrevendo apenas seu escopo local.

2. Convenções de Estilo

  • Idioma: Português Brasileiro (pt-BR) é o padrão. Termos técnicos canônicos (ex: Maturidade Causal) devem ser preservados.
  • Nomenclatura: Arquivos .md usam kebab-case (ex: meu-novo-guia.md).
  • Links: Use sempre caminhos relativos (ex: ../architecture/kernel.md). Links absolutos quebram o build.

3. Metadados e Cabeçalhos

Não use YAML frontmatter. O mdBook renderiza YAML como texto visível. Em vez disso, use comentários HTML no topo do arquivo:

<!-- title: Título da Página -->
<!-- audience: novos desenvolvedores -->
<!-- status: DRAFT -->

4. Diagramas (Mermaid)

Prefira diagramas code-first usando Mermaid.js. Eles são fáceis de versionar e eficientes para LLMs processarem.

graph TD;
    A-->B;
    A-->C;

5. Checklist de Documentação

  • O arquivo usa kebab-case?
  • Os links são todos relativos?
  • O metadado está em comentários HTML?
  • Usei o Dicionário para termos técnicos?
  • Adicionei a nova página ao SUMMARY.md?

6. Veja também

🌐 Internacionalização (i18n)

Embora o português brasileiro (pt-BR) seja o idioma canônico do PAEBIRU, o sistema é projetado para ser global.


1. Prioridade de Idiomas

  1. pt-BR: Idioma da documentação de core, RFCs e comentários de código.
  2. en-US: Idioma para visibilidade internacional e SDKs.
  3. es-ES: Idioma para integração regional na América Latina.

2. Padrões de Tradução

  • Termos Canônicos: Termos como Maturidade Causal, Algedonia e Plasmídeo devem ser traduzidos seguindo o glossário oficial para evitar perda de significado técnico.
  • Mensagens de Erro: O Kernel emite códigos de erro numéricos, que são traduzidos na camada de API ou CLI para o idioma do usuário.

3. Como Contribuir

Se você deseja traduzir uma página da documentação:

  1. Crie uma pasta com o código do idioma (ex: docs/src/en/).
  2. Mantenha a estrutura de arquivos idêntica à de docs/src/.
  3. Utilize o comando make i18n-check para verificar se há páginas faltando no idioma traduzido.

4. Veja também

❄️ Realidade Fractal

O PAEBIRU segue o Padrão Antropofágico: a mesma estrutura funcional repete-se em múltiplas escalas. Esta auto-similaridade garante que as garantias de segurança e eficiência sejam mantidas do bit à malha global.


1. As 7 Escalas Fractais

O ciclo metabólico (ingerir → metabolizar → excretar) ocorre em:

  1. Bit Físico: A unidade mínima de custo termodinâmico.
  2. Neurônio LIF: A unidade de processamento neuromórfico (SNN).
  3. Função WASM: A unidade lógica dentro de um plasmídeo.
  4. Plasmídeo: A unidade de governança e contrato.
  5. Nó ABAPORU: A unidade de soberania individual.
  6. LocalSyncDomain: O cluster local de alta confiança (Fog).
  7. Malha Global: O organismo completo.

2. Por que a fractalidade?

  • Escalabilidade: Se um protocolo funciona para coordenar 10 funções em um plasmídeo, ele pode ser adaptado para coordenar 10 nós em um cluster.
  • Resiliência: Falhas em uma escala não colapsam o sistema inteiro, pois cada nível mantém sua própria Homeostasia e sensores algedônicos.
  • Simplicidade Cognitiva: Desenvolvedores e agentes de IA precisam aprender apenas um padrão fundamental que se aplica a todo o sistema.

3. Invariantes em todas as escalas

  • Backpressure: Nenhuma escala pode ser forçada a processar mais do que sua capacidade metabólica permite.
  • Recibos: Toda interação gera uma prova de execução/valor.
  • Maturidade Causal: O tempo é sempre medido pela progressão de eventos e não por relógios externos.

4. Veja também

🧬 Sistema Celular

No PAEBIRU, o nó não é apenas um servidor; ele é uma célula. Esta metáfora biológica dita como os recursos são geridos e como a segurança é enforçada.


1. A Membrana (ZeroTrustPipeline)

Toda célula tem uma membrana que protege seu interior e regula o que entra e sai. No nó, essa membrana é o ZeroTrustPipeline (os 5 portões).

  • Seletividade: Apenas pacotes com PoW válido e assinaturas PQC atravessam a membrana.
  • Proteção: A membrana é a primeira linha de defesa contra exaustão de recursos (Load Shedding).
flowchart LR
    A[Pacote bruto<br/>UDP/TCP/LoRa] --> P1[Portão 1<br/>eBPF/XDP<br/>load shedder]
    P1 --> P2[Portão 2<br/>PoW BLAKE3<br/>anti-Sybil]
    P2 --> P3[Portão 3<br/>PQC ML-DSA<br/>assinatura]
    P3 --> P4[Portão 4<br/>CDDL contrato<br/>+ ZK-PoL se geo]
    P4 --> P5[Portão 5<br/>MacrophageVM<br/>sandbox + anticorpo]
    P5 --> AC[Aceito · CausalBlock]
    P1 -.drop.-> X[(drop metric)]
    P3 -.drop.-> X
    P5 -.quarentena.-> Q[MacrophageVM]

2. Metabolismo Local

O processamento interno do nó segue um ciclo metabólico:

  1. Ingestão: Recebimento de mensagens e estímulos (spikes).
  2. Digestão: Processamento via loop GALS e execução de plasmídeos.
  3. Excreção: Emissão de Recibos Soberanos e propagação de novos estímulos para a malha.

3. Apoptose e Homeostasia

  • Homeostasia: O nó busca manter seu equilíbrio térmico e computacional através de sensores algedônicos.
  • Apoptose: Se um componente (plasmídeo ou cache) torna-se disfuncional ou perigoso, o nó realiza a “morte programada” daquele recurso para preservar a integridade da célula.

4. Veja também

🖥️ SO Distribuído

PAEBIRU atua como um Sistema Operacional Distribuído, onde o “hardware” é a malha global de nós heterogêneos.


1. O Kernel como Microkernel

O paebiru-kernel funciona como um microkernel moderno:

  • Gerenciamento de Processos: Cada plasmídeo é um processo isolado em uma sandbox WASM.
  • IPC (Inter-Process Communication): A troca de mensagens via GossipSub atua como o barramento de sistema (System Bus).
  • Drivers: O BC de HAL fornece a interface para o hardware físico.

2. Abstração de Recursos

Diferente de um SO tradicional que gerencia uma CPU local, o PAEBIRU abstrai a capacidade computacional da vizinhança causal:

  • Agendamento de Enxame: O scheduler distribui tarefas baseando-se na energia disponível e na latência termodinâmica dos nós vizinhos.
  • Memória Causal: O C.A.P.I.B.A. atua como a memória virtual do sistema, onde os dados são endereçados por conteúdo (IPLD) e não por endereço físico.

3. Soberania de Execução

No SO Distribuído do PAEBIRU, não há “usuário root” global. A autoridade é derivada de Recibos Soberanos e consenso de quórum, garantindo que o sistema opere de forma justa e resiliente a falhas de nós individuais.


4. Veja também

🦴 Kernel — Espinha Dorsal

O Kernel é o Bounded Context que implementa o loop GALS (Globally Asynchronous, Locally Synchronous) do nó. Ele é a única peça que conhece rede, threads e tempo — o restante dos BCs (biology, economy, capiba, learning, etc.) é puro domínio e se comunica com o Kernel via troca de mensagens.

flowchart LR
    subgraph Adapters [adapters/ · E/S]
        NET[NetworkPort<br/>libp2p]
        TIME[TimePort<br/>tokio::time]
        RES[ResourcePort<br/>sysinfo]
    end
    subgraph Ports [ports/ · traits de I/O]
        P1[NetworkPort]
        P2[TimePort]
        P3[ResourcePort]
    end
    subgraph Types [ports/ · tipos canônicos]
        T1[PeerId]
        T2[MetabolicMessage]
        T3[SystemPressure]
    end
    subgraph Actor [actor/ · loop GALS]
        KA[KernelActor<br/>mpsc receiver]
    end
    subgraph Domain [domain/ · núcleo puro]
        M[Metabolism<br/>peer health +<br/>token bucket]
    end
    NET -.implementa.-> P1
    TIME -.implementa.-> P2
    RES -.implementa.-> P3
    P1 --> KA
    P2 --> KA
    P3 --> KA
    KA -->|handle_message<br/>carrega T1, T2, T3| M
    M -->|MetabolicAction| KA
    KA -->|send_message| P1

Regra de dependência: domain/ nunca importa de actor/, ports/ ou adapters/. A seta vai do actor para o domain — nunca o contrário. Esta é a aplicação do Dogma 1 (Isolamento Hexagonal) ao Kernel.

0.1. O coração metabólico: Token Bucket

O Metabolism é o algoritmo central do GALS: um token bucket canônico com MAX_TOKENS=100 e recarga de 0.1 tokens/ms. Cada mensagem consome 1 token; sem tokens, o ator não bloqueia — ele marca a mensagem como saturada, dispara sinal algedônico e segue. É a implementação concreta do princípio de Backpressure universal.

flowchart LR
    I[Inbound msg] --> R[Refill<br/>tokens = min MAX, t + tokens]
    R --> C{tokens >= 1?}
    C -- não --> S[Saturated<br/>drop + algedonic]
    C -- sim --> H[handle_message]
    H --> T[tokens -= 1]
    T --> A[MetabolicAction<br/>processa e despacha]
    S -.sinal.-> ALG[AlgedonicSensor]
    A --> O[Outbound msg]

1. Anatomia do crate

crates/kernel/src/
├── lib.rs           # exports públicos
├── actor/
│   └── mod.rs       # KernelActor, KernelCommand, KernelHandle
├── domain/
│   └── mod.rs       # Metabolism, MetabolicAction, PeerHealth
├── ports/
│   └── mod.rs       # PeerId, MetabolicMessage, NetworkPort, TimePort, ResourcePort, SystemPressure
└── adapters/
    └── mod.rs       # (vazio por enquanto — implementações concretas virão aqui)
MóduloCamada hexagonalResponsabilidade
domain/NúcleoLógica pura: tracking de peers, backpressure, decisão metabólica
ports/PortasTraits assíncronos que o domínio “vê” do mundo
actor/AplicaçãoLoop GALS que conecta domínio a portas
adapters/AdaptadoresImplementações concretas de portas (rede, tempo, recursos)

2. Domínio (crates/kernel/src/domain/)

Metabolism

A única estrutura que carrega estado mutável do domínio. Não tem I/O, não tem threads, não tem tokio. É testável em isolamento absoluto com um relógio mockado.

#![allow(unused)]
fn main() {
pub struct Metabolism {
    node_id: PeerId,
    known_peers: HashMap<PeerId, PeerHealth>,
    tokens: f32,            // token bucket (backpressure)
    last_refill_ms: u64,
}
}

Constantes de metabolismo:

ConstanteValorSignificado
MAX_TOKENS100.0Capacidade máxima do bucket
REFILL_RATE_PER_MS0.1100 tokens / segundo

Algoritmo:

  1. Em cada handle_message, primeiro reabastece o bucket proporcional a now_ms - last_refill_ms.
  2. Se tokens < 1.0, retorna MetabolicAction::Saturated (sem consumir).
  3. Senão, consome 1 token e processa a mensagem.
  4. Para PulseRequest: registra/atualiza o PeerHealth do emissor e agenda PulseResponse.
  5. Para PulseResponse: atualiza o health_score do emissor.

MetabolicAction

#![allow(unused)]
fn main() {
pub enum MetabolicAction {
    SendResponse { target: PeerId, msg: MetabolicMessage },
    UpdateInternalState,
    Saturated,   // backpressure sinalizou overload
    None,
}
}

Invariante: Metabolism::handle_message é puro — dado o mesmo (sender, msg, now_ms) e o mesmo estado inicial, produz a mesma MetabolicAction. Isso é verificável por proptest.

PeerHealth

#![allow(unused)]
fn main() {
pub struct PeerHealth {
    pub last_seen_ms: u64,
    pub health_score: f32,
}
}

health_score ∈ [0.0, 1.0]; valores perto de 0 indicam peer degradado e disparam o sensor algedônico (futuro: roteamento adaptativo).


3. Portas (crates/kernel/src/ports/)

Definem tudo que o domínio vê do mundo, sem saber quem implementa.

PeerId

#![allow(unused)]
fn main() {
pub struct PeerId([u8; 32]);
}

32 bytes opacos. Display mostra os primeiros 8 bytes em hex (para logs).

MetabolicMessage

#![allow(unused)]
fn main() {
pub enum MetabolicMessage {
    PulseRequest  { timestamp: u64 },
    PulseResponse { timestamp: u64, health: f32 },
}
}

Por enquanto, apenas duas variantes — hello da malha. O conjunto crescerá conforme os outros BCs (biology, economy) enviarem mensagens de domínio. Cada nova variante é uma mudança compatível para trás (apenas adição), preservável por versionamento de envelope.

NetworkPort (assíncrono)

#![allow(unused)]
fn main() {
#[async_trait]
pub trait NetworkPort: Send + Sync {
    /// Envia uma mensagem metabólica para um peer específico.
    async fn send_message(&self, target: PeerId, msg: MetabolicMessage) -> Result<(), &'static str>;

    /// Broadcast de uma mensagem para todos os peers conhecidos.
    async fn broadcast(&self, msg: MetabolicMessage) -> Result<(), &'static str>;
}
}

Implementação concreta atual: apps/node/src/network.rs (libp2p).

TimePort (síncrono)

#![allow(unused)]
fn main() {
pub trait TimePort: Send + Sync {
    fn now_ms(&self) -> u64;
}
}

Síncrono de propósito: facilita proptest (testes determinísticos bancam o tempo com um contador). Não usar Instant::now() diretamente no domínio.

ResourcePort (síncrono)

#![allow(unused)]
fn main() {
pub trait ResourcePort: Send + Sync {
    fn get_current_pressure(&self) -> SystemPressure;
}
}

SystemPressure é o que alimenta o sensor algedônico do nó (local, sem supervisor global).

#![allow(unused)]
fn main() {
pub struct SystemPressure {
    pub cpu_usage: f32,     // [0.0, 1.0]
    pub memory_usage: f32,  // [0.0, 1.0]
    pub disk_usage: f32,    // [0.0, 1.0]
}
}

4. Ator (crates/kernel/src/actor/)

KernelCommand

Mensagens que o Node (camada de fora) envia para o ator:

#![allow(unused)]
fn main() {
pub enum KernelCommand {
    IncomingMessage { sender: PeerId, message: MetabolicMessage },
    TriggerPulse,
    Shutdown,
}
}

KernelActor

#![allow(unused)]
fn main() {
pub struct KernelActor {
    metabolism: Metabolism,
    network_port: Arc<dyn NetworkPort>,
    time_port:   Arc<dyn TimePort>,
    resource_port: Arc<dyn ResourcePort>,
    receiver:    mpsc::Receiver<KernelCommand>,
}
}

O loop principal:

#![allow(unused)]
fn main() {
pub async fn run(mut self) {
    while let Some(command) = self.receiver.recv().await {
        match command {
            KernelCommand::IncomingMessage { sender, message } => {
                let now = self.time_port.now_ms();
                let action = self.metabolism.handle_message(sender, message, now);
                self.execute_action(action).await;
            }
            KernelCommand::TriggerPulse => { /* pulso metabólico */ }
            KernelCommand::Shutdown => break,
        }
    }
}
}

Regra do Dogma 2 (GALS): o loop do ator nunca bloqueia em I/O. Toda chamada externa é async e awaitada; o mpsc::Receiver é o único ponto de suspensão.

KernelHandle

pub use em lib.rs — é a handle que o Node usa para enviar comandos ao ator:

#![allow(unused)]
fn main() {
pub struct KernelHandle {
    sender: mpsc::Sender<KernelCommand>,
}
}
#![allow(unused)]
fn main() {
impl KernelHandle {
    pub async fn incoming(&self, sender: PeerId, msg: MetabolicMessage) -> Result<(), ...>;
    pub async fn trigger_pulse(&self) -> Result<(), ...>;
    pub async fn shutdown(&self) -> Result<(), ...>;
}
}

5. Adaptadores (crates/kernel/src/adapters/)

Por enquanto apenas:

#![allow(unused)]
fn main() {
pub mod networking {}
}

A implementação concreta está em apps/node/src/network.rs — uma decisão consciente: o Kernel é uma biblioteca no_std-friendly que não inclui libp2p. A integração com a rede física vive no Node (binário). Em fases futuras, a tendência é mover implementações para cá para reuso em outros front-ends (CLI, playground, simulator).


6. Fluxo end-to-end (exemplo)

Uma mensagem chegando do libp2p:

sequenceDiagram
    participant N as Network (libp2p)
    participant H as KernelHandle
    participant A as KernelActor (loop)
    participant D as Metabolism (domain)
    participant R as ResourcePort
    N->>H: incoming(sender, PulseRequest)
    H->>A: mpsc::send(IncomingMessage)
    A->>R: get_current_pressure()
    A->>D: handle_message(sender, msg, now)
    D-->>A: MetabolicAction::SendResponse
    A->>N: network_port.send_message(...)
    N-->>Sender: PulseResponse

Garantia: todo o caminho passa por um único thread (o loop do ator). Não há Mutex no Metabolism — a imutabilidade estrutural do actor é o “lock”.

Transporte e descoberta do pulso

A integração libp2p concreta vive em apps/node/src/network.rs. O pulso trafega em gossipsub (tópico paebiru-metabolism), que é o canal de publicação efêmero e ponto-a-ponto. Os peers que assinam este tópico são descobertos por duas camadas complementares:

  • mDNS (LAN) — plug-and-play local, sem configuração.
  • Kademlia DHT (global) — anel de peers roteáveis, alimentado por PAEBIRU_BOOTNODES. O gate F1 do Roadmap (“dois nós trocam pulse ponta-a-ponta via libp2p Kademlia”) é satisfeito pela combinação Kademlia-para-descoberta + gossipsub-para-transporte; o pulso não é armazenado como Kademlia Record — ele é efêmero por design (ver Pulse no Dicionário).

O Dogma 1 (Hexagonal) é preservado: este BC não conhece libp2p, mDNS ou Kademlia. Toda a complexidade de transporte vive no Node (apps/node), satisfazendo o NetworkPort que o KernelActor consome. O Dogma 3 (no_std) também permanece intacto — o paebiru-kernel continua compilável para riscv32imc-unknown-none-elf e thumbv7em-none-eabihf.


7. Como testar

Tipo de testeOndeO que cobre
Unitário (#[test])crates/kernel/src/domain/testsMetabolism puro — proptest! sobre (sender, msg, now)
Integraçãocrates/kernel/tests/actor_loop.rsKernelActor::run com NetworkPort mockado
Property-basedcrates/kernel/proptest-recipesInvariante: tokens ∈ [0, MAX_TOKENS]
no_stdcargo check --target riscv32imc-unknown-none-elfdomain/ compila sem std

Cobertura-alvo: ≥ 90 % (enforçada por make coverage).


8. O que não é Kernel

  • Persistênciacapiba.md (outro BC).
  • Aprendizado / modelos → BC learning.
  • Crédito / Loteria Joule → BC economy.
  • Agentes BDI / SNN → BC biology.
  • Definição de plasmídeos → BC plasmids.

Se a mudança que você quer fazer não é loop de ator, porta ou adaptação de E/S, provavelmente é outro BC.


9. Veja também

🌿 Biologia — O Organismo

O Bounded Context de Biologia implementa a camada cognitiva e metabólica do PAEBIRU. Enquanto o kernel cuida da sobrevivência mecânica (rede, mensagens), a biologia cuida da sobrevivência adaptativa: como o nó percebe o ambiente, como toma decisões (ABAPORU) e como economiza energia via redes neuromórficas (SNN).

flowchart TB
    subgraph Inputs [Percepção]
        S[Sensores Algedônicos]
        M[Mensagens da Malha]
    end
    subgraph Cognition [Cognição · ABAPORU]
        B[Crenças · Beliefs]
        D[Desejos · Desires]
        I[Intenções · Intentions]
    end
    subgraph Execution [Metabolismo]
        SNN[SNN · Spiking Neural Network]
        BC[Backpressure Causal]
    end
    Inputs --> B
    B --> D
    D --> I
    I --> Execution
    Execution -->|Feedback| S

1. ABAPORU — Agente BDI

O ABAPORU é o agente autônomo que reside em cada nó. Ele segue o modelo BDI (Belief-Desire-Intention):

  • Beliefs (Crenças): Representam o que o nó sabe sobre o mundo (estado dos peers, maturidade causal, topologia da malha).
  • Desires (Desejos): Objetivos de alto nível (manter latência baixa, maximizar créditos, economizar bateria).
  • Intentions (Intenções): Planos concretos de ação (re-rotear pacotes, iniciar round de FedAvg, entrar em hibernação).

2. Redes Neuromórficas (SNN)

Para processamento de ultra-baixa energia, especialmente em MuleNodes, a biologia utiliza Spiking Neural Networks (SNN) com neurônios LIF (Leaky Integrate-and-Fire).

  • Sparsity: A informação é transmitida via spikes (pulsos) no tempo. Se não há atividade, não há consumo de CPU.
  • Hardware-Aware: A rede ajusta sua densidade (sparsity) com base no sinal de dor (algedonia) do hardware.

3. Metabolismo e Homeostasia

O nó é tratado como uma célula metabólica. O sistema busca manter a homeostasia através de:

  • Sensores Algedônicos: Monitoram temperatura, CPU e memória. Se o “prazer” cai abaixo do limiar, o nó entra em modo defensivo.
  • Veto Algedônico: Um mecanismo de segurança onde o hardware pode interromper a governança lógica para evitar dano físico (ex: superaquecimento).
  • Backpressure: O metabolismo do nó dita o ritmo de processamento. O MetabolicAction do Kernel é o sinal de “fome” ou “saciedade” do sistema.

4. Invariantes do Domínio

  1. Soberania Decisória: O ABAPORU local sempre tem a palavra final sobre o uso de seus recursos.
  2. Prioridade Termodinâmica: A sobrevivência física do nó (homeostasia) precede qualquer objetivo da malha.
  3. Maturidade Causal: Decisões de aprendizado e evolução seguem o tempo de Langevin, não o cronológico.

5. Veja também

💸 Economia — O Tecido

O Bounded Context de Economia é o tecido que conecta os nós através de incentivos materiais e reciprocidade. No PAEBIRU, a economia não é baseada em moedas fiduciárias centralizadas, mas em recursos termodinâmicos reais (energia, computação, banda) e crédito mútuo.

flowchart LR
    subgraph DRE [Distributed Receipt Engine]
        R[Recibo Soberano]
    end
    subgraph Engine [Barter & Ledger]
        B[Barter Engine]
        LL[Landauer Ledger]
        MC[Crédito Mútuo]
    end
    subgraph Rewards [Incentivos]
        LJ[Loteria Joule]
        DAO[Governança DAO]
    end
    R --> B
    B --> MC
    MC --> LL
    LL --> LJ
    LJ --> DAO

1. DRE — Distributed Receipt Engine

Toda interação econômica no PAEBIRU gera um Recibo Soberano.

  • Imutabilidade: Assinado via ML-DSA (Portão 3).
  • Auditabilidade: Persistido no C.A.P.I.B.A. para verificação futura.
  • Prova de Valor: O recibo contém o custo energético da operação em micro-joules (µJ).

2. Barter Engine e Crédito Mútuo

O PAEBIRU utiliza um sistema de permuta (barter) e crédito mútuo de soma zero:

  • Bilateralidade: Dois nós podem trocar recursos diretamente (ex: banda por armazenamento).
  • Multilateralidade: A malha realiza a compensação de saldos entre múltiplos nós periodicamente.
  • Soma Zero: Não existe criação de “moeda” do nada; o crédito de um nó é o débito de outro, mantendo o equilíbrio do sistema.

3. Loteria Joule

A Loteria Joule é o mecanismo de recompensa para nós que contribuem com poder computacional real para a malha:

  • Input: Provas de trabalho e contribuições de aprendizado federado.
  • Output: Distribuição de direitos de prioridade e créditos na malha.
  • Termodinâmica: Baseada no custo de Landauer; quem economiza energia para a malha é recompensado.

4. Landauer Ledger

O livro-razão fundamental do sistema. Ele registra o débito termodinâmico de cada operação.

  • Cada portão do ZeroTrustPipeline tem um custo fixo em µJ.
  • O ledger garante que a computação não seja tratada como gratuita, prevenindo abusos e ataques de negação de serviço econômico.

5. Invariantes do Domínio

  1. Soma Zero: O balanço global de créditos e débitos deve ser sempre zero.
  2. Materialidade: Todo crédito deve ser lastreado em contribuição real de recurso (energia/computação/dado).
  3. Privacidade: As transações preservam a soberania do nó; detalhes granulares são revelados apenas sob quorum.

6. Veja também

🌊 C.A.P.I.B.A. — Memória Persistente Causal

Causal, Asynchronous, Persistent, Immutable Block Architecture — a memória de longo prazo do PAEBIRU. Onde o kernel cuida da mensagem em trânsito, o capiba cuida da mensagem em repouso: como ela se torna dado, como o dado se torna conhecimento, e como o conhecimento se preserva no tempo causal.

flowchart LR
    subgraph Hot [Hot path · µs–ms]
        N[1. Nascente<br/>Ring Buffer / RAM]
    end
    subgraph Warm [Warm path · ms–s]
        C[2. Correnteza<br/>MmapStore / WAL<br/>Prolly Trees]
        M[3. Manguezal<br/>Arrow in-memory<br/>+ Zero-Trust filter]
    end
    subgraph Cold [Cold path · s–min]
        O[4. Oceano<br/>Iceberg + IPLD CIDs]
    end
    subgraph Volatile [Volatile · min–h]
        Ch[5. Chuva<br/>Compute-over-data<br/>→ Plasmídeo WASM]
    end
    N -->|Langevin Tick| C
    C -->|Pororoca Causal<br/>sync P2P| M
    M -->|Transmutação Analítica<br/>Parquet| O
    O -->|Compute-over-Data| Ch
    Ch -->|Precipitação<br/>Evolutiva| N

Princípio-guia: C.A.P.I.B.A. não é “um banco de dados” — é um ecossistema metabólico de dados com 5 estágios análogos ao ciclo hidrológico. Cada estágio tem temperatura termodinâmica, formato de representação e função diferentes. Nada “vira storage” por inércia; cada bloco é causalmente endereçado e tem uma vida útil declarada pelo seu MUS (Minimum Useful Survival).


1. Fronteira do BC

TipoO que é C.A.P.I.B.A.O que não é
Em escopoPersistência causal, content addressing, sincronização MuleNode, DRE (Data Refinery Engine), schema evolution (Iceberg), compute-over-data, retenção/apoptoseTransporte de mensagem em rede (→ kernel)
Em escopoIPLD CIDs, BLAKE3, Prolly Trees, Apache Arrow/Parquet/IcebergTreinamento de modelos ML (→ learn)
Em escopoPolíticas MUS, Landauer Gate, Sovereignty GateDefinição de plasmídeos (→ plasmids)
Em escopoSincronização Pororoca CausalDecisões de governança/DAO (→ economy)
Em escopoAssinatura de bloco (assinatura de bloco, não autenticação de identidade)Identidade soberana (→ kernel)

Membranas existem por uma razão: se o problema não é de dados, é de outro BC. Devolva o ticket; não estique a membrana.


2. Os 5 estágios

Cada estágio é um trade-off explícito entre latência, consistência e custo termodinâmico. A escolha do estágio é arquitetural, não operacional — não se move dado entre estágios por conveniência.

2.1 Nascente (Hot) — capiba::ring

  • Função: captura de evento no momento de criação.
  • Representação: ring buffer lock-free em RAM; ~µs de latência.
  • Transição para o próximo: Langevin Tick — quando o bloco resfria (i.e., outros nós da sua vizinhança causal já o viram), é despejado no WAL.
  • Consistência: estritamente local; sem replicação.
  • Limite de tamanho: PAEBIRU_NASCENTE_RING_BYTES (default 256 MB).
  • Anti-padrão: usar Nascente como fila durável. Não é.

2.2 Correnteza (Warm) — capiba::mmap::wal + capiba::prolly

  • Função: buffer causal, replicável entre nós da LocalSyncDomain.
  • Representação: MmapStore (WAL posix) + Prolly Tree indexada por DVV.
  • Transição para o próximo: Pororoca Causal — batched sync P2P com delta-sync via Bloom filter.
  • Consistência: causal (não cronológica).
  • Filtros: StigmergicImmuneSystem — pacotes que violam invariante causal são desviados para o Manguezal como “lama tóxica”.
  • MuleNodes (LoRa, ATmega): usam Pororoca com janelas Langevin estendidas, eventualmente consistente.

2.3 Manguezal (Cool) — capiba::arrow

  • Função: análise intermediária + quarentena Zero-Trust.
  • Representação: Apache Arrow in-memory; transações vetoriais columnares.
  • Transição para o próximo: Transmutação Analítica — quando o bloco passa no filtro Zero-Trust (CDDL + validação semântica + ZK-PoL se houver geolocalização), é despejado em Parquet e preparado para o Oceano.
  • Consistência: forte eventual; semântica “read-your-writes” no mesmo nó.
  • Quarentena: blocos suspeitos → MacrophageVM (ver Tópicos em formalização) para síntese de anticorpos. Nunca se executa o conteúdo de um bloco em Manguezal sem passar pelo Portão 5 (CDDL).

2.4 Oceano (Cold) — capiba::iceberg + capiba::ipfs

  • Função: cold storage soberano, auditável, replicado via erasure coding entre nós da Confederation Tier.
  • Representação: Apache Iceberg (snapshot lineage) + IPLD CID v1 com multicodec + multihash (BLAKE3).
  • Transição para o próximo: Erasure Coding + Sovereignty Gate — antes de descer, dados são auditados. Sovereignty Gate verifica soberania (não violação de jurisdição, não dado pessoal sem máscara, etc.).
  • Consistência: eventual; snapshots imutáveis.
  • Migração irreversível: uma vez no Oceano, o dado é tratado como fato histórico. Mudanças exigem novo bloco causal.

2.5 Chuva (Volatile) — capiba::compute

  • Função: compute-over-data. Gradientes para treino federado; pesos viram plasmídeo (regra distribuída).
  • Representação: trainer federado (FLAIR/Ising) que consome Iceberg manifest e emite WeightDelta.
  • Transição para o próximo: Precipitação Evolutiva — WeightDelta vira plasmídeo WASM (ver Tópicos em formalização) com versão própria.
  • Idempotência: aplicar o mesmo plasmídeo duas vezes = aplicar uma única vez. Chuva é convergente.
  • Anti-padrão: Chuva que move o Oceano. Compute vai até o storage; storage nunca vai até o compute.

3. Modelo de dados canônico

ConceitoTipo canônicoFunçãoOnde vive
CausalBlockstruct { content_hash: BLAKE3, dvv: DottedVersionVector, payload: Bytes, signature: MlDsa65 }Unidade imutável básicacapiba::domain::block
DottedVersionVectorstruct { node_id: PeerId, counter: u64 } (par)Base de maturidade causalcapiba::domain::dvv
ProllyTreeárvore Merkle com rolling hashSync delta eficientecapiba::prolly
IpfsCidnewtype — CID v1, multicodec, multihash BLAKE3Content addressing globalcapiba::ipfs::cid
MusThresholdconst por tipo de blocoMaturidade mínima para retençãocapiba::domain::mus
MuleReceiptstruct { origin: PeerId, batch_id, dvv_window }Recibo de sync MuleNodecapiba::mule
IcebergManifeststruct { schema_id, snapshot_id, partition_spec, lineage }Schema evolutioncapiba::iceberg::manifest
QuantumReceiptstruct { block: CausalBlock, from_stage, to_stage, joules, timestamp }Recibo de transmutaçãocapiba::domain::transmutation

Invariante fundamental: todo bloco carrega seu DVV. Nenhum bloco é persistido sem DVV válido (verificável contra qualquer peer da vizinhança causal).


4. Princípios operacionais (vinculantes)

  1. Tempo causal, não cronológico. Ordenação por DVV. Instant::now() e timestamps de wall-clock nunca são fonte de verdade para ordenação.
  2. Content addressing. Endereço é o par (BLAKE3(conteúdo), DVV). Mesmo conteúdo em maturidades diferentes = CIDs diferentes.
  3. Apoptose saudável. MUS define a maturidade abaixo da qual o bloco evapora. Não é “limpeza” — é metabolismo.
  4. Sovereignty Gate. Antes de Oceano, audit (CDDL + semântica + ZK-PoL se houver geolocalização).
  5. Compute-over-data > move-data. Compute vai até o storage.
  6. Quarentena imunológica. Manguezal é filtro Zero-Trust; lama tóxica → MacrophageVM.
  7. Sincronização MuleNode. Pororoca Causal: batched, eventual, com _receipts_ imutáveis.
  8. Backpressure de I/O. Profundidade finita no WAL; produtor adapta-se ao consumidor (jamais buffer infinito).

Violação de qualquer um destes princípios é regressão automática.


5. Tipos de operação

FamíliaLatênciaConsistênciaEstágioExecutor típico
IngestãoµsEventual localNascenteABAPORU IoT
SincronizaçãomsCausalCorrentezaMuleNode + DHT
AnálisesForte eventualManguezal/OceanoFog/Cloud node
Computaçãomin–hIdempotenteChuvaEdge trainer

6. Tópicos a formalizar (vinculantes a médio prazo)

Estes tópicos precisam virar RFC ratificada antes de mudanças no contrato público do C.A.P.I.B.A.:

  • Definição e motivação do C.A.P.I.B.A.; Prolly Trees
  • CIDs IPLD + content addressing BLAKE3
  • Apoptose — esquecimento saudável (MUS)
  • Iceberg catalog no Oceano
  • Landauer Gate — custo termodinâmico da retenção
  • Fail-stop em 7 escalas (também C.A.P.I.B.A.)

A lista canônica e o estado de cada tópico vivem em RFCs em construção. Mudanças em qualquer um destes pontos exigem RFC ratificada (ver processo).


7. Relação com outros BCs

flowchart LR
    K[kernel<br/>mensagem em trânsito] -->|receipt| CAP[capiba<br/>mensagem em repouso]
    B[biology<br/>ABAPORU] -->|causal events| CAP
    E[economy<br/>Loteria Joule] -->|WeightDelta| CAP
    L[learn<br/>FedAvg] -->|gradient sync| CAP
    Z[zk<br/>ZK-PoL proofs] -->|sovereignty proofs| CAP
    CAP -->|compute-over-data| L
    CAP -->|stored receipts| E
    CAP -->|snapshots| AP[api<br/>query federada]
  • kernelcapiba: todo receipt soberano é persistido como CausalBlock; toda leitura de receipt é via DVV (não por timestamp).
  • biologycapiba: eventos de ABAPORU (crença, desejo, intenção) viram blocos causais; memória de longo prazo do agente = Nascente + Correnteza.
  • learncapiba: trainer federado (Chuva) consome Iceberg (Oceano) e emite plasmídeo (precipitação).
  • economycapiba: o DRE (Data Refinery Engine) usa C.A.P.I.B.A. como insumo canônico para o LandauerLedger.
  • zkcapiba: provas de ZK-PoL entram no Sovereignty Gate antes da migração para Oceano.

8. Quando não é C.A.P.I.B.A.

  • “Mensagem demora para chegar” → kernel, não dados.
  • “Modelo não converge” → learn, não dados.
  • “Quem pode escrever X?” → economy + DAO, não dados.
  • “Como assino bloco Y?” → kernel (segurança), não dados.

9. Padrões de mudança

Adicionar coluna a um schema Iceberg

  1. Migration no DRE (capiba::dre::migrations).
  2. Atualizar MusThreshold se a coluna afeta retenção.
  3. Atualizar este documento.
  4. Teste de round-trip causal (escreve → lê em DVV maior → compara).
  5. make test + fuzzing de serialização Iceberg.

Adicionar política de apoptose (MUS)

  1. Invariante formal em TLA+ (capiba/formal/).
  2. Implementação em capiba::domain::apoptosis.
  3. Teste property-based com maturidades aleatórias.
  4. Verificar que a Landauer Gate não viola $k_B \cdot T \cdot \ln 2$.
  5. Métrica Prometheus: paebiru_capiba_apoptosis_total.

Criar novo MuleNode adapter (CAN bus, Modbus)

  1. Implementar capiba::ports::MuleTransport.
  2. Adapter em capiba::adapters::mule::<tecnologia>.
  3. Garantir no_std compatível.
  4. cargo check --target thumbv7em-none-eabihf.
  5. Atualizar este documento (tabela de estágios, se aplicável).

10. Checklist para mudanças em capiba

  • A mudança é no C.A.P.I.B.A. e não em outro BC?
  • Timestamps de wall-clock não são usados para ordenação (DVV)?
  • Content addressing (BLAKE3/IPLD) é usado, não path?
  • MUS/Apoptose foram considerados?
  • Se toca rede/cripto, paebiru-security foi consultado?
  • Se toca ML/inferência, paebiru-ai foi consultado?
  • Testes property-based para invariantes causais?
  • cargo test -p paebiru-capiba + --target thumbv7em-none-eabihf se aplicável?
  • Documentação (este arquivo) atualizada?

Veja também

🌀 Entropia

O Bounded Context de Entropia é o fundamento termodinâmico do PAEBIRU. Ele gerencia o tempo, o custo da informação e o equilíbrio energético do sistema, transformando leis da física em regras de protocolo.


1. Landauer Ledger

Baseado no Princípio de Landauer, que estabelece o custo energético mínimo para apagar um bit de informação ($k_B T \ln 2$):

  • Custo de Esquecimento: Toda vez que o sistema descarta dados (limpeza de cache, expiração de logs), há um custo computacional e energético associado.
  • Escassez Real: A computação no PAEBIRU não é tratada como infinita; ela é limitada pela capacidade do nó de dissipar calor e gerir sua entropia.

2. Langevin Ticks e Tempo Termodinâmico

O tempo no PAEBIRU não segue apenas o relógio de silício, mas a Dinâmica de Langevin:

  • Δt ∝ ΔS / γ: O tempo avança proporcionalmente à variação de entropia ($\Delta S$) e inversamente ao atrito termodinâmico ($\gamma$).
  • Dança Politemporal: Diferentes partes da malha podem operar em ritmos diferentes (escalas de tempo) dependendo de sua atividade metabólica.

3. Sensor Algedônico e Homeostasia

A entropia monitora a “desordem” do sistema através de feedback sensorial:

  • Dor (Pain): Aumento de entropia não controlada (vazamento de memória, loops infinitos) dispara sinais algedônicos de dor.
  • Prazer (Pleasure): Estados de baixa entropia e alta eficiência geram sinais de prazer, incentivando o nó a manter aquele estado.

4. Invariantes do Domínio

  1. Conservação de Energia: O custo de processamento deve ser sempre contabilizado no LandauerLedger.
  2. Irreversibilidade: Operações que modificam o estado global são tratadas como processos termodinâmicos irreversíveis.
  3. Equilíbrio Local: Cada nó busca o seu próprio estado de mínima energia através de otimização estocástica (Langevin SGD).

5. Veja também

🧠 Aprendizado

O Bounded Context de Aprendizado implementa a inteligência distribuída do PAEBIRU através de Aprendizado Federado (Federated Learning). Aqui, o conhecimento é construído de forma colaborativa sem que os dados brutos jamais saiam de seus nós de origem.


1. Arquitetura Federada

O PAEBIRU utiliza um modelo de federação descentralizada:

  • FedAvg (Federated Averaging): Algoritmo padrão para agregação de pesos de modelos.
  • Deltas de Peso: Os nós treinam localmente e enviam apenas a diferença (delta) dos pesos, reduzindo drasticamente o uso de banda.
  • Agregação Bizantina: Mecanismos como Krum e FoolsGold são usados para detectar e descartar contribuições maliciosas ou ruidosas.

2. Split-DNN e Privacidade

Para modelos complexos que não cabem inteiramente em um MuleNode, utilizamos Split-DNN:

  • Fatiamento: A rede neural é dividida. O nó de borda executa as primeiras camadas (extração de features) e um nó de fog/cloud executa as camadas finais.
  • Differential Privacy: Adição de ruído controlado aos gradientes para garantir que informações sensíveis não possam ser reconstruídas.

3. Hardware-Aware Learning (FLAIR)

O aprendizado é sensível ao estado físico do nó através do framework FLAIR:

  • Pruning Adaptativo: Se um nó está com bateria baixa ou alta temperatura (Algedonia), ele reduz a densidade do modelo (pruning) para economizar energia.
  • Quantização Dinâmica: Alternância entre precisão total (FP32) e quantização agressiva (INT4/INT8) com base na disponibilidade de recursos.

4. Integração com Plasmídeos

O resultado de um round de aprendizado federado é frequentemente encapsulado em um Plasmídeo:

  1. O agregador consolida os pesos.
  2. Os novos pesos são injetados em um template de plasmídeo.
  3. O plasmídeo é assinado via FROST (assinaturas distribuídas).
  4. A nova “inteligência” é propagada pela malha.

5. Invariantes do Domínio

  1. Soberania do Dado: Dados brutos nunca são transmitidos.
  2. Resiliência Bizantina: O sistema deve convergir mesmo com uma porcentagem de nós adversariais.
  3. Maturidade Causal: Rounds de aprendizado são ordenados via DVV para evitar ataques de replay ou confusão temporal.

6. Veja também

🔌 API

O Bounded Context de API é a membrana de comunicação externa do nó PAEBIRU. Ele expõe as capacidades do sistema para o mundo exterior através de interfaces REST e gRPC, garantindo observabilidade e auditabilidade através de Recibos Soberanos.


1. Recibos Soberanos (DRE)

A principal saída da API não são apenas dados, mas Recibos Soberanos gerados pelo Distributed Receipt Engine (DRE):

  • Verificabilidade: Cada resposta da API é acompanhada por uma assinatura criptográfica pós-quântica (ML-DSA).
  • Prova de Execução: O recibo serve como prova de que uma computação ou transação ocorreu em um determinado nó sob certas condições.
  • Monetização: Recibos podem ser usados para liquidação no BC de Economia.

2. Interface HTTP (Axum)

A implementação padrão utiliza o framework Axum para oferecer uma interface de alto desempenho:

  • Endpoints de Saúde: /healthz e /readiness para orquestração.
  • Métricas: /metrics no formato Prometheus para monitoramento de metabolismo.
  • Comandos: Endpoints para injeção de plasmídeos e consulta de estado causal.

3. Observabilidade e Tracing

O PAEBIRU segue o padrão OpenTelemetry (OTel) para garantir que cada mensagem possa ser rastreada através da malha:

  • Distributed Tracing: Uso de tracing e opentelemetry para correlacionar eventos entre nós.
  • Logs Estruturados: Logs em formato JSON para fácil ingestão por sistemas como Grafana Loki.
  • Sensores de Stress: A API expõe o estado dos sensores algedônicos para sistemas de monitoramento externos.

4. Invariantes do Domínio

  1. Segurança por Default: Nenhum endpoint de mutação de estado é exposto sem autenticação mútua (mTLS) ou prova de identidade soberana.
  2. Backpressure de API: Se o nó estiver saturado (metabolismo alto), a API retorna 429 Too Many Requests com base nos tokens do Kernel.
  3. Idempotência: Operações de mutação devem ser idempotentes através de identificadores únicos no cabeçalho da API.

5. Veja também

🌉 Bridges Web3

O Bounded Context de Bridges é a ponte que conecta o PAEBIRU a outros ecossistemas descentralizados. Ele permite que a malha PAEBIRU consuma oráculos, armazene dados em redes de preservação e interaja com identidades de IoT externas.


1. Filecoin / IPFS (Armazenamento)

Para dados que excedem a capacidade de retenção local (Oceano) ou que exigem persistência global de longo prazo:

  • IPLD: O PAEBIRU utiliza CIDs IPLD nativamente para endereçamento de conteúdo.
  • Filecoin Deals: A ponte automatiza a criação de storage deals para persistir snapshots críticos da malha em provedores Filecoin.

Para injetar dados do mundo real ou de outras blockchains de forma confiável:

  • Price Feeds: Consumo de preços de ativos para a Barter Engine.
  • VRF (Verifiable Random Function): Uso de aleatoriedade auditável para a seleção de quóruns e sorteios na Loteria Joule.
  • Functions: Execução de scripts externos que alimentam as crenças (Beliefs) do ABAPORU.

3. IoTeX (Identidade IoT)

Para integração com hardware soberano e dispositivos de borda já existentes:

  • W3bstream: Integração com a camada de computação off-chain da IoTeX para prova de eventos físicos.
  • DID: Mapeamento de identidades IoTeX para PeerIDs do PAEBIRU, permitindo que dispositivos IoTeX participem da malha como MuleNodes.

4. Invariantes do Domínio

  1. Abstração de Protocolo: O Kernel não sabe que está falando com a Ethereum ou Filecoin; ele interage com BridgePorts genéricos.
  2. Minimização de Confiança: Toda ponte deve incluir verificação local de provas (ex: proofs de inclusão Merkle) sempre que possível.
  3. Assincronia Estrita: Interações com redes externas lentas nunca devem bloquear o metabolismo local do nó.

5. Veja também

📦 Commons

O Bounded Context de Commons contém os tipos fundamentais, macros e utilitários que são compartilhados por todos os outros crates do workspace. Ele é a “gramática” básica do PAEBIRU.


1. Tipos Fundamentais

O Commons define as estruturas que atravessam as membranas de todos os BCs:

  • Identificadores: PeerId, PlasmidId, ReceiptId.
  • Envelopes de Mensagem: Estruturas genéricas de transporte que garantem serialização e deserialização consistente (FlatBuffers/Serde).
  • Resultados e Erros: Tipos de erro canônicos que facilitam o tratamento de falhas em cascata.

2. Macros e Utilitários

Para manter o código DRY (Don’t Repeat Yourself) sem violar o isolamento:

  • Logging: Wrappers sobre tracing que injetam contexto metabólico (Langevin Ticks) em todos os logs.
  • Profiling: Ferramentas de medição de performance no_std compatíveis.
  • Validation: Macros para validação de invariantes em tempo de compilação e execução.

3. Invariantes do Domínio

  1. Minimalismo: O Commons deve ter o mínimo de dependências possível.
  2. Estabilidade: Por ser a base do grafo de dependências, mudanças no Commons devem ser raras e extremamente bem testadas.
  3. Pureza: O Commons não deve conter lógica de negócio específica de nenhum outro BC.

4. Por que commons e não utils?

No PAEBIRU, evitamos o termo utils para desencorajar o acúmulo de código sem propósito claro. O Commons representa recursos compartilhados que são propriedade coletiva de todos os contextos, seguindo a metáfora de bens comuns.


5. Veja também

⚙️ HAL Embarcado

O Bounded Context de HAL (Hardware Abstraction Layer) é o que permite ao PAEBIRU rodar em dispositivos com recursos extremamente limitados, como microcontroladores de 8, 16 e 32 bits. Ele segue o Dogma 3 (no_std First).


1. Suporte a Hardware

O PAEBIRU HAL é projetado para ser agnóstico, suportando diversas arquiteturas através de traits do embedded-hal.

ArquiteturaTargets ExemploEstado
RISC-Vriscv32imc-unknown-none-elf🟢 Suportado
ARM Cortex-Mthumbv7em-none-eabihf🟢 Suportado
XtensaESP32, ESP32-S3🟡 Em testes
AVRATmega 328P🟠 Planejado

2. Primitivas no_std

Para garantir a execução em ambientes sem sistema operacional (bare-metal), o HAL utiliza:

  • Gerenciamento de Memória: Uso extensivo de heapless para coleções de tamanho fixo em stack, evitando fragmentação de heap.
  • Criptografia Leve: Implementações otimizadas de BLAKE3 e assinaturas PQC que cabem em menos de 100 KB de ROM.
  • Concorrência: Baseada em interrupções e loops cooperativos (RTIC ou similar).

3. Periféricos e MuleNodes

Os MuleNodes são nós de borda que utilizam o HAL para se comunicar com o mundo físico:

  • Sensores: GPIO, ADC, I²C, SPI para captura de dados metabólicos.
  • Comunicação: Drivers para LoRa (SX1262), CAN bus e Modbus RTU.
  • Energy Harvesting: Lógica de gerenciamento de energia para nós alimentados por painéis solares ou vibração.

4. Invariantes do Domínio

  1. Eficiência Estrita: Cada ciclo de clock e byte de RAM deve ser justificado (Dogma 3).
  2. Abstração Transparente: O domínio do HAL expõe traits genéricos para que o kernel e biology possam rodar o mesmo código lógico em x86 ou RISC-V.
  3. Resiliência de Boot: O HAL deve garantir um estado seguro de boot mesmo em condições de baixa voltagem.

5. Veja também

🧬 Plasmídeos

O Bounded Context de Plasmídeos é a fábrica de código de contrato do PAEBIRU. Cada plasmídeo é um pequeno programa auto-contido, escrito em uma DSL de alto nível (TOML/HCL), compilado para WebAssembly e executado dentro de uma membrana do BC C.A.P.I.B.A. — o plasmídeo é, ao mesmo tempo, código e dado: ele migra entre nós como um CausalBlock imutável.

⚠️ Stub documental. O crate paebiru-plasmids ainda não está implementado no workspace (somente o kernel está materializado em crates/). Este arquivo existe para (a) desbloquear o build do mdBook em modo strict — o SUMMARY.md precisa de um capítulo apontando para o BC Plasmídeos — e (b) servir de contrato canônico para a primeira implementação. Ver ROADMAP §Fase 2 e tópico em formalização.


1. Fronteira do BC

TipoO que é PlasmídeosO que não é
Em escopoSintaxe da DSL (TOML/HCL), parser, AST, compilador para WASM, assinatura pós-compilação, versionamento, empacotamento como CausalBlockExecução do WASM em si (→ kernel + wasmtime)
Em escopoVinculação a host imports (WASI-PAEBIRU ABI), limites de recursos, contratos de dados (CDDL)Persistência do estado do plasmídeo (→ capiba)
Em escopoCatálogo de plasmídeos canônicos (transferência, validação, atestação)Distribuição/libp2p dos plasmídeos pela malha (→ kernel)
Em escopoSandbox de teste e “playground” para autoresPolítica econômica de execução (→ economy)

2. Estado atual e roadmap


3. Invariantes do Domínio

  1. Determinismo: Um mesmo plasmid.toml deve produzir um mesmo plasmid.wasm byte-a-byte (content addressing estável).
  2. Imutabilidade pós-compilação: o plasmídeo, uma vez compilado e assinado, é um CausalBlock — não é editável, apenas substituído.
  3. Sandbox obrigatório: zero syscalls fora do host imports declarado; o wasmtime aplica fuel e memória limitada.
  4. Recibos Soberanos: toda execução emite um recibo DRE com referência ao CID do plasmídeo (ver Dicionário · DRE).
  5. Idempotência de invocação: o mesmo (plasmid_cid, input_cid) produz o mesmo (output_cid, receipt_cid).

4. Veja também

🔐 ZK (Zero-Knowledge)

O Bounded Context de ZK é a oficina de provas de conhecimento zero do PAEBIRU. Sua função canônica é a ZK-PoL (Proof of Location — provar que o nó está dentro de uma região geográfica sem revelar suas coordenadas exatas), mas também abriga provas de integridade de modelos federados e de correção de rollback C.A.P.I.B.A. O canônico é Groth16 sobre BN254, com arkworks como backend.

⚠️ Stub documental. O crate paebiru-zk ainda não está implementado no workspace (somente o kernel está materializado em crates/). Este arquivo existe para (a) desbloquear o build do mdBook em modo strict — o SUMMARY.md precisa de um capítulo apontando para o BC ZK — e (b) servir de contrato canônico para a primeira implementação. Ver tópico em formalização.


1. Fronteira do BC

TipoO que é ZKO que não é
Em escopoGeração de chaves de prova, setup (SRS), circuit para ZK-PoL (Haversine + bounding-box), serialização de provas Groth16Criptografia de transporte / Noise / TLS (→ kernel)
Em escopoVerificação de provas (verifier otimizado para no_std quando possível)Assinaturas pós-quânticas ML-DSA / ML-KEM (→ kernel)
Em escopoComposição de provas (rollup de várias PoL em um único recibo)Política de quando uma PoL é exigida (→ decisão de protocolo)
Em escopoBindings C-ABI para SDKs de outras linguagens (ver Dogma 4)Hospedagem do wasmtime (→ kernel)

2. Estado atual e roadmap

  • Pré-Fase 3 — apenas especificado.
  • O modelo matemático está descrito em Referência · Matemática.
  • A prova de ZK-PoL combina (a) constraint Haversine para a distância geodésica com (b) constraint bounding-box para o raio autorizado, sem revelar a posição exata.
  • Quando o nó rodando em MCU restrito não pode gerar a prova localmente, ela é delegada a um nó vizinho com attestation — o resultado entra como CausalBlock separado assinado por AMBOS os nós.

3. Invariantes do Domínio

  1. Soundness acima de tudo: nenhuma prova aceita sem verificação completa do verifier; verificação parcial é proibida (anti-class: trusted setup trap).
  2. SRS público e verificável: a structured reference string deve ser gerada por cerimônia pública verificável; nunca SRS descartável.
  3. Sem replay: cada prova inclui um nonce causal derivado do DVV atual — provas velhas não são reusáveis.
  4. Falha visível: prova inválida → recibo com verdict=reject
    • entrada no MacrophageVM para análise; nunca fail-silent.
  5. Pós-quântico em roadmap: Groth16/BN254 é o canônico de Fase 3; transição para STARKs ou PLONK sobre curvas pós-quânticas será objeto de nova RFC.

4. Veja também

🧠 Neuromórfica

A visão neuromórfica trata a malha PAEBIRU como um cérebro sintético, onde cada nó é um neurônio e as mensagens são sinapses.


1. Processamento Baseado em Eventos

Diferente do processamento contínuo, a arquitetura neuromórfica reage a mudanças. O uso de SNN (Spiking Neural Networks) permite que o sistema permaneça em estado de baixa energia até que um estímulo relevante ocorra.


2. Plasticidade Sináptica

A rede aprende e se adapta através da mudança de “pesos” nas rotas de GossipSub. Caminhos que transmitem informações úteis (Recibos Soberanos validados) tornam-se mais fortes, enquanto rotas ruidosas são atrofiadas.


3. Computação no Substrato

A meta de longo prazo é rodar o PAEBIRU em hardware neuromórfico dedicado (ex: Loihi), explorando a física do silício para realizar computação de baixíssima entropia.

🚀 Espaço

PAEBIRU no espaço: Lidando com latências extremas, radiação e janelas de comunicação intermitentes.


1. Maturidade Causal em Longas Distâncias

Em redes espaciais, o tempo cronológico perde o sentido devido ao atraso de propagação. A Maturidade Causal (DVV) permite que satélites e estações terrestres se sincronizem sem depender de um relógio comum estável.


2. Tolerância a Falhas e Radiação

O sistema utiliza Reed-Solomon e redundância biológica (múltiplas cópias de plasmídeos) para sobreviver a corrupções de memória causadas por radiação cósmica, recuperando o estado a partir de peers vizinhos.


3. MuleNodes Orbitais

Satélites de órbita baixa (LEO) atuam como MuleNodes, transportando “lotes de conhecimento” entre regiões da Terra que não possuem conectividade direta via rádio ou fibra.

⚔️ Tática

Operação do PAEBIRU em cenários contestados, onde a rede pode sofrer interferência deliberada (jamming) ou censura agressiva.


1. Ofuscação de Tráfego

Uso de transporte mutável (libp2p multi-transports) para esconder o tráfego da malha dentro de outros protocolos ou através de saltos de frequência em rádio (LoRa).


2. Redes de Emergência

Em cenários de desastre, o PAEBIRU cria redes ad-hoc imediatas. A identidade soberana garante que o comando e controle permaneçam íntegros mesmo sem infraestrutura de internet.


3. ZK-PoL para Validação de Campo

Uso de Proof of Location para garantir que uma informação (ex: relatório de sensor) venha realmente da coordenada geográfica alegada, sem revelar a posição exata do operador para o inimigo.

🏛️ Governança

No PAEBIRU, a governança não é um processo burocrático externo, mas uma propriedade intrínseca do código e da economia, gerida por Plasmídeos de Governança.


1. Soberania Individual

Cada nó é soberano sobre sua identidade e recursos. Nenhuma decisão global pode forçar um nó a agir contra seu Veto Algedônico.


2. DAOs Estigmérgicas

Decisões coletivas emergem do rastro deixado pelos nós na malha. Propostas são plasmídeos que atraem ou repelem o “voto” (recursos computacionais) dos participantes conforme sua maturidade causal.


3. Voto Quadrático e Crédito Mútuo

O peso nas decisões de governança é balanceado pelo saldo no LandauerLedger, utilizando mecanismos como voto quadrático para evitar a plutocracia e incentivar a contribuição real para o ecossistema.

🌫️ Fog Computing

A visão de Fog Computing posiciona o PAEBIRU como a camada de “névoa” que reside entre os dispositivos IoT (edge) e a nuvem (cloud).


1. Hierarquia de Tiers

  • Edge Tier: MuleNodes processando dados locais e emitindo recibos.
  • Fog Tier: Nós de alta performance realizando agregação federada (FedAvg) e armazenamento quente (Correnteza).
  • Cloud Tier: Snapshots imutáveis e auditoria global (Oceano).

2. Escalonamento Adaptativo

O scheduler de enxame utiliza o Hamiltoniano de Ising para distribuir tarefas de computação entre os nós da névoa, minimizando a latência e o consumo de energia total do cluster local.


3. Island Mode

Em caso de perda de conexão com a WAN, o cluster de névoa entra em Modo Ilha, mantendo a operação local e sincronizando o estado causal assim que a conectividade for restaurada.

🏭 Bioindustrial

Esta visão descreve a aplicação do PAEBIRU em ambientes de automação industrial, biorreatores e infraestrutura crítica, onde a resiliência e a Homeostasia são vitais.


1. Monitoramento Metabólico

Em uma planta industrial, sensores Modbus e CAN bus são tratados como entradas metabólicas. O nó PAEBIRU local atua como uma membrana que filtra o ruído e emite apenas sinais de relevância (spikes) para a malha.


2. Controle Descentralizado

Diferente de PLCs centrais, o controle é distribuído em Agentes ABAPORU que residem em cada máquina. Eles se coordenam estigmergicamente para otimizar o fluxo de produção sem depender de um servidor SCADA centralizado.


3. Segurança Crítica

O ZeroTrustPipeline garante que comandos de controle (plasmídeos) sejam validados criptograficamente antes da execução, protegendo a planta contra sabotagem digital ou injeção de comandos maliciosos.

🧠 Fundamentos teóricos

Por trás de cada decisão de projeto no PAEBIRU há um fundamento teórico — cognitivo, termodinâmico, ou de coordenação. Esta seção é a trilha conceitual: leia antes (ou durante) mergulhar no código.

Ensaios canônicos

EnsaioPergunta que responde
Arquitetura cognitivaComo o PAEBIRU pensa — agentes BDI, SNN, atenção
Protocolos de coordenaçãoComo agentes concordam — quorum, estigmergia, gossip
Fundamentos termodinâmicosComo o PAEBIRU respira — Landauer, Langevin, Dança Politemporal

Leituras externas recomendadas

Esta é uma biblioteca comentada, não uma checklist. Escolha por interesse e tempo disponível.

Cibernética & sistemas adaptativos

  • W. Ross Ashby — An Introduction to Cybernetics (1956) — livro-texto fundador; “lei da variedade requerida” é a base do nosso sensor algedônico.
  • Donella Meadows — Thinking in Systems (2008) — vocabulário para “membrana” e “estoque vs fluxo”.
  • Francisco Varela, Humberto Maturana, Ricardo Uribe — Autopoiesis — a base生物学 do nosso modelo de “célula de malha”.

Distribuídos & consenso

  • Leslie Lamport — Time, Clocks, and the Ordering of Events (1978) — a referência de Maturidade Causal.
  • Diego Ongaro, John Ousterhout — In Search of an Understandable Consensus Algorithm (Raft, 2014) — referência para a parte síncrona local.
  • Cynthia Dwork, Nancy Lynch, Larry Stockmeyer — Consensus in the Presence of Partial Synchrony (1988) — modelo de partição.

Termodinâmica da computação

  • Rolf Landauer — Irreversibility and Heat Generation in the Computing Process (1961) — base do LandauerLedger.
  • Edward Nelson — Dynamical Theories of Brownian Motion (1967) — referência para a equação de Langevin.
  • Luca Peliti — Statistical Mechanics in a Nutshell (2011) — capítulo sobre o Hamiltoniano de Ising.

Neuromórfica

  • Wolfgang Maass — Networks of Spiking Neurons (1997) — base da nossa SNN.
  • Carver Mead — Analog VLSI and Neural Systems (1989) — base do HAL neuromórfico.

Como ler

  1. Se você é novato no projeto: comece por Arquitetura cognitiva.
  2. Se você está mexendo em consenso / partição: vá para Protocolos de coordenação.
  3. Se você está mexendo em scheduler / backpressure: Fundamentos termodinâmicos.

Veja também

🧠 Arquitetura Cognitiva

O PAEBIRU não é apenas um sistema de mensagens; ele é um organismo distribuído. Sua arquitetura cognitiva é baseada no modelo ABAPORU, que combina a lógica clássica de agentes autônomos com a biologia neuromórfica.


1. O Agente ABAPORU (BDI)

Cada nó PAEBIRU executa uma instância do ABAPORU, seguindo o framework Belief-Desire-Intention (BDI):

  • Percepção: O nó recebe estímulos (spikes da SNN, mensagens do gossipsub, sinais algedônicos).
  • Crenças (Beliefs): O nó mantém um grafo causal do ambiente.
  • Desejos (Desires): Objetivos latentes (ex: manter-se energizado, processar rounds de aprendizado).
  • Intenções (Intentions): Compromissos de ação imediata (ex: assinar um recibo, propagar um plasmídeo).

2. Redes de Spikes (SNN) e Atenção

Diferente das IAs tradicionais de “caixa preta”, a cognição do PAEBIRU é esparsa e temporal:

  • SNN (Spiking Neural Networks): Neurônios LIF (Leaky Integrate-and-Fire) processam informações apenas quando ocorrem mudanças significativas (spikes), reduzindo o custo termodinâmico.
  • Atenção Estigmérgica: O nó foca sua capacidade computacional em áreas da malha onde o “rastro” (estigmergia) é mais forte, permitindo uma coordenação global sem supervisor central.

3. Algedonia e Feedback Homeostático

A cognição é guiada por dor e prazer:

  • Sinais de Dor: Saturação de recursos, ataques detectados ou perda de conectividade.
  • Sinais de Prazer: Eficiência energética, convergência de modelos e integridade causal.
  • Loop de Feedback: O agente ajusta seu comportamento para minimizar a dor e maximizar a Homeostasia local.

4. Cognição Fractal

A inteligência é recursiva:

  1. Uma função WASM tem uma cognição primitiva de entrada/saída.
  2. Um plasmídeo coordena várias funções.
  3. Um coordena plasmídeos.
  4. A malha coordena nós. Cada escala utiliza o mesmo ciclo de processamento, mudando apenas a complexidade das crenças.

5. Veja também

🤝 Protocolos de Coordenação

No PAEBIRU, a coordenação entre milhares de nós heterogêneos não é feita por comando central, mas por mecanismos emergentes inspirados em sistemas biológicos e sociais.


1. Estigmergia e Coordenação Indireta

A Estigmergia é o mecanismo onde os agentes se coordenam modificando o ambiente:

  • Rastros Causais: Cada Receipt e CausalBlock deixa um rastro no storage (C.A.P.I.B.A.) e na rede.
  • Atração de Atenção: Novos plasmídeos e mensagens são atraídos para áreas de alta atividade estigmérgica, criando uma organização natural de carga.

2. GossipSub e Difusão Epidêmica

O transporte de informação segue modelos epidemiológicos:

  • Gossip: As informações (pulsos, recibos, plasmídeos) “vazam” entre nós vizinhos.
  • Robustez: Mesmo com falhas massivas de nós, a informação eventualmente alcança todos os interessados devido à redundância inerente ao protocolo GossipSub.
  • Backpressure de Rede: O fluxo de gossip é limitado pelo metabolismo do nó, evitando tempestades de broadcast.

3. Consenso por Maturidade Causal (DVV)

Ao contrário de blockchains que exigem uma ordem linear global (timestamp ou bloco), o PAEBIRU utiliza Maturidade Causal:

  • Dotted Version Vectors (DVV): Capturam a relação “aconteceu-antes” (happened-before).
  • Consenso Local: Pequenos grupos de nós (LocalSyncDomains) concordam com o estado causal de forma rápida, sem esperar a malha global.
  • Convergência Eventual: A malha global converge para o estado de maior maturidade causal ao longo do tempo.

4. Quóruns Adaptativos e FROST

Para operações críticas que exigem confiança:

  • FROST: Uso de assinaturas de limiar (threshold signatures) onde $t$ de $n$ nós assinam uma decisão.
  • Identidade Distribuída: A soberania não reside em um nó, mas na capacidade do grupo de gerar um recibo válido.

5. Veja também

⚡ Fundamentos Termodinâmicos

O PAEBIRU é construído sobre a premissa de que a computação é um processo físico sujeito às leis da termodinâmica. Ignorar o custo energético da informação leva a sistemas centralizados e ineficientes.


1. Princípio de Landauer e o Custo do Esquecimento

O físico Rolf Landauer demonstrou que apagar um bit de informação dissipa calor: $$Q \geq k_B T \ln 2$$

  • LandauerLedger: Cada operação de segurança e armazenamento no PAEBIRU debita um custo termodinâmico real.
  • Incentivo à Eficiência: Algoritmos que minimizam a entropia (esquecimento desnecessário) são economicamente favorecidos na malha.

2. Dinâmica de Langevin e o Tempo

O tempo no sistema não é uma constante cronológica, mas uma variável da Dinâmica de Langevin:

  • Δt ∝ ΔS / γ: O tempo (o tick do sistema) avança apenas quando há variação de entropia ($\Delta S$) vencendo o atrito metabólico ($\gamma$).
  • Estocasticidade: O sistema aceita o ruído como parte natural do processo de busca por estados de equilíbrio (Langevin SGD).

3. Homeostasia e Dissipação de Calor

Cada nó deve manter seu equilíbrio térmico e de recursos:

  • Algedonia: O sistema de dor/prazer é a representação subjetiva do estado entrópico do nó.
  • Veto Algedônico: A proteção física final do nó contra a exaustão térmica.
  • Metabolismo: A taxa na qual o nó pode “digerir” informação sem entrar em colapso.

4. Computação de Baixa Entropia

O uso de SNN (Spiking Neural Networks) e Zero-Copy visa reduzir a dissipação de energia:

  • Zero-Copy: Evitar cópias de memória reduz o trabalho físico total.
  • Sparsity: Processar apenas o que muda (spikes) preserva a energia do nó para tarefas críticas.

5. Veja também

📖 Dicionário canônico

Este documento é a fonte de verdade para todos os termos técnicos do PAEBIRU. Em caso de divergência entre este dicionário, o AGENTS.md, comentários de código ou RFCs, este dicionário prevalece até que uma RFC Standards Track atualize-o formalmente.

Convenção: cada entrada traz a forma canônica em pt-BR, a sigla, o termo em inglês quando útil, e a referência à RFC que o ratifica (se houver).


A

ABAPORU (Agente BDI)

Nome em tupi para “homem que come”) — agente de crença-desejo-intenção que opera no BC Biologia. Implementação canônica em paebiru-biology.

Veja tópico em formalização e BC Biology.

Algedonia / Algedonic Sensor

Literalmente, “dor e prazer” (do grego algos + hedone). Sensor que emite sinais de dor quando a homeostasia é violada (temperatura, memória, backpressure, saturação XDP) e prazer quando o sistema opera dentro da faixa saudável. Cada escala tem o seu — não existe supervisor global.

tópico em formalização.

Anti-padrão “Costura”

Acoplamento por tipo ou estado compartilhado entre Bounded Contexts (Arc<Mutex<T>> cruzando membrana). Sintoma de fronteira mal colocada. Refatora-se a membrana; nunca se costura.

tópico em formalização.

Anti-padrão “supervisor global”

Qualquer coordenador que conhece o estado de N escalas abaixo. Empurre a decisão para a escala que sofre a consequência.

tópico em formalização.

Auto-similaridade fractal (Padrão Antropofágico)

O ciclo ingerir → metabolizar → excretar repete-se em 7 escalas: bit físico → neurônio LIF → função WASM → plasmídeo → nó ABAPORU → LocalSyncDomain → malha global.

tópico em formalização, Realidade fractal.

Antígeno / Anticorpo

Antígeno: pacote ou plasmídeo marcado como suspeito pelo ZeroTrustPipeline. Anticorpo: plasmídeo WASM sintetizado pela MacrophageVM após análise do antígeno; subsequentemente distribuído como “imunidade” aos outros nós.

tópico em formalização.


B

Backpressure universal

O produtor adapta-se ao consumidor mais lento via sinal explícito (token bucket, créditos). Nunca buffer infinito. A forma é idêntica em streaming payments, FL gradient updates e gossipsub fanout.

tópico em formalização.

BLAKE3

Função de hash criptográfica usada em toda a pilha (PoW, DVV, identidade, integridade de plasmídeos). Preferida sobre SHA-256 por throughput, tree hashing nativo e segurança pós-quântica marginal.

tópico em formalização.

Bounded Context (BC)

Granularidade vertical do PAEBIRU: cada BC mapeia 1:1 com um crate. Comunica-se com outros BCs apenas por artefatos imutáveis com receipt. Lista canônica: kernel, biology, economy, capiba, entropy, learning, api, bridges, commons, hal, zk, plasmids.

Arquitetura.

Convenção editorial: grafia sempre em Title Case — Bounded Context e Bounded Contexts (plural), mesmo em meio de frase. A forma minúscula bounded context(s) é reservada a citações textuais do termo DDD genérico.


C

CausalBlock

Unidade imutável básica do C.A.P.I.B.A.: tupla (cid, maturidade, dados, assinaturas) endereçada por content ID (BLAKE3). É o “átomo” que migra entre estágios (Nascente → Correnteza → Manguezal → Oceano → Chuva) e entre nós (via Pororoca Causal). Recebe um Recibo Soberano (DRE) a cada transição de estágio.

BC C.A.P.I.B.A..

C.A.P.I.B.A. (Causal, Asynchronous, Persistent, Immutable Block Architecture)

A memória de longo prazo do PAEBIRU — onde kernel lida com a mensagem em trânsito, capiba lida com a mensagem em repouso: como ela vira dado, como o dado vira conhecimento, e como o conhecimento se preserva no tempo causal. Não é “um banco de dados”: é um ecossistema metabólico de dados organizado em 5 estágios análogos ao ciclo hidrológico:

#EstágioFunçãoRepresentação canônica
1NascenteIngestão hot-pathRing buffer / RAM lock-free
2CorrentezaSincronização causalMmapStore / WAL + Prolly Trees
3ManguezalQuarentena + análiseApache Arrow in-memory + filtro Zero-Trust
4OceanoCold storage soberanoApache Iceberg + IPLD CIDs (BLAKE3)
5ChuvaCompute-over-dataTrainer federado → WeightDelta → Plasmídeo

Princípios vinculantes (cada item é rejeição automática em revisão):

  1. Tempo causal, não cronológico — ordenação por DVV, jamais por Instant::now().
  2. Content addressing — blocos endereçados por (hash_conteúdo, maturidade_causal), não por path.
  3. Apoptose saudávelMUS (Minimum Useful Survival) define a maturidade abaixo da qual o dado evapora; a Landauer Gate assegura que o custo termodinâmico da retenção respeite $k_B \cdot T \cdot \ln 2$.
  4. Sovereignty Gate — antes de descer para o Oceano, dados são auditados (CDDL + validação semântica + ZK-PoL se houver geolocalização).
  5. Compute-over-data > move-data — a Chuva (compute) vai até o Oceano (storage), não o contrário.
  6. Quarentena imunológica — o Manguezal é filtro Zero-Trust; “lama tóxica” vai para MacrophageVM.
  7. Sincronização MuleNode — MuleNodes (LoRa, ATmega) sincronizam via Pororoca Causal — batched, eventual, com receipts imutáveis.
  8. Backpressure de I/O — profundidade finita do WAL; produtor adapta-se ao consumidor (jamais buffer infinito).

Quando $\Delta C \to 0$ (taxa de novas interações com o bloco) e a maturidade causal excede MUS, o dado evapora do Manguezal para o Oceano. Quando $\Delta C \to 0$ no Oceano, ele pode ser chuva — entrar em compute-over-data para virar um plasmídeo (regra distribuída).

RFCs normativas: tópico em formalização (definição), tópico em formalização (CID IPLD), tópico em formalização (apoptose), tópico em formalização (Iceberg), tópico em formalização (Landauer Gate). BC doc canônico: architecture/bounded-contexts/capiba.md.

CDDL (Concise Data Definition Language)

Linguagem usada para definir o contrato de dados no Portão 5 do ZeroTrustPipeline. Validação semântica antes de qualquer plasmídeo ser executado.

tópico em formalização.

Cifra ChaCha20-Poly1305

Cifra simétrica AEAD canônica do PAEBIRU. Usada em todos os envelopes de plasmídeo e em sessões TLS-like entre nós.

tópico em formalização.

CommonCrypto

Sinônimo coloquial para a pilha criptográfica canônica: BLAKE3 + ed25519-dalek + FROST + ML-DSA/ML-KEM + ChaCha20-Poly1305.

Compute-over-data

Padrão pelo qual o dado permanece no nó de origem e a computação viaja até ele — oposto do modelo “traga o dado até o lago”. Custódia, soberania e economia são co-locadas.

BC C.A.P.I.B.A..

Crédito mútuo (DRE)

Sistema de crédito bilateral plurilateral, soma zero, sem juros explicitos. Liquidação por compensação multilateral periódica. NÃO é “criptomoeda”: é um tecido entre agentes que se conhecem.

tópico em formalização, tópico em formalização.

Convenção editorial: grafia sempre em Title Case quando substantivo próprio (Crédito mútuo). A forma adjetiva creditário mútuo é aceitável apenas em textos técnicos formais sobre o modelo.


D

Dança Politemporal (v3+)

Regime temporal em que $\Delta t \propto \Delta S / \gamma$ — o “tempo” se dilata quando a entropia cresce, e se contrai quando nada varia. Múltiplos “tempos” coexistem sem hierarquia.

tópico em formalização, BC Entropia.

DRE (Distributed Receipt Engine)

Motor de Recibos Soberanos. Cada interação produz um recibo imutável com hash, assinatura ML-DSA, timestamp causal e custo em LandauerLedger. É a unidade atômica de prova.

tópico em formalização.

DVV (Dotted Version Vector)

Estrutura que captura maturidade causal, não cronologia. Cada nó tem um vetor de versões por origem; um evento “amadurece” quando todos os seus dependentes causais também amadureceram. É a base da Maturidade Causal.

tópico em formalização.


E

eBPF / XDP

Tecnologia Linux para executar programas no kernel com segurança. O Portão 1 (Load Shedder) do ZeroTrustPipeline é um programa XDP carregado pelo paebiru-kernel via aya.

tópico em formalização.

Estigmergia

Coordenação indireta entre agentes via modificação do ambiente compartilhado. No PAEBIRU: rastros de plasmídeo, receipt em WAL, memória C.A.P.I.B.A., e gradiente algedônico.

tópico em formalização.


F

Fail-stop em 7 escalas

Falha imediata, sem retry silencioso, em qualquer das 7 escalas fractais. Acima de um limiar algedônico, o nó emite Veto Algedônico e interrompe a operação local; nunca propaga falha.

tópico em formalização.

FedAvg / Split-DNN / FLAIR

Família de algoritmos de aprendizado federado suportados em paebiru-learn. Agregação bizantina (Krum, FoolsGold) é obrigatória em redes > 50 nós.

tópico em formalização, tópico em formalização.

FROST (Flexible Round-Optimized Schnorr Threshold)

Esquema de assinaturas threshold (DPSS) usado para chaves distribuídas. Em 3-de-5, três nós assinam; dois podem sair do ar sem perda de soberania.

tópico em formalização.


G

GALS (Globally Asynchronous, Locally Synchronous)

Paradigma fundamental: atores localmente síncronos, comunicação globalmente assíncrona via troca de mensagens. Dogma 2 .

Arquitetura.

GossipSub

Protocolo de publish-subscribe baseado em gossip do libp2p. É o transporte default de plasmídeos e receipts.


H

HAL (Hardware Abstraction Layer)

Runtime no_std para ESP32, STM32, nRF52, ATmega e RISC-V. Fornece traits de GPIO, ADC, UART, I²C, SPI, LoRa, CAN, Modbus.

BC HAL.

Hardware Wallet

Dispositivo físico que custodia a chave de identidade soberana (comunica-se com TPM ou Secure Enclave). Suportado em paebiru-hal com bindings USB.

tópico em formalização.

HardwarePassport

Dispositivo físico de backup de identidade soberana — distinto do Hardware Wallet. O Passport é um artefato off-line (sem conectividade, à prova de tamper) que carrega (a) a chave mestra criptografada por biometria/PUK, (b) o último DVV conhecido do nó, e (c) o último Recibo Soberano assinado. Usado no protocolo de Disaster Recovery quando o nó primário é perdido (ver R011 · Disaster recovery).

Homeostasia

Tendência de um sistema a manter variáveis internas dentro de uma faixa saudável. Emerge de sensores algedônicos locais, sem supervisor global.


I

Ilha de autonomia

Regime operacional em que um conjunto de nós opera sem WAN, com partição interna. Sincroniza DVV e receipts quando reconecta.

tópico em formalização.

Convenção editorial: grafia canônica Ilha de autonomia ou forma abreviada Modo Ilha (ambas aceitas). A forma inglesa Island mode é proibida em documentação pt-BR.

Imunidade distribuída

Conjunto de anticorpos (plasmídeos WASM) compartilhados entre nós após análise em MacrophageVM. Não é uma blacklist central — é conhecimento emergente.


L

LandauerLedger

Livro de débitos energéticos. Cada operação no ZeroTrustPipeline debita um custo em µJ (PAEBIRU_GATE_SECURITY_COST_MICRO_JOULES). É a base de reciprocidade material do crédito mútuo.

BC Entropia.

Landauer Gate

Portão termodinâmico que decide se um CausalBlock tem energia associada suficiente para ser retido, ou se deve evaporar. A regra operacional respeita o princípio de Landauer: o custo mínimo de apagar 1 bit é $k_B \cdot T \cdot \ln 2$ joules. Se o custo de retenção (energia de armazenamento + indexação) excede o benefício causal ($\Delta C$), o portão dispara apoptose saudável e o bloco migra para o Oceano ou evapora.

BC C.A.P.I.B.A. · Princípios.

Langevin Ticks

Unidade de tempo baseada na dinâmica de Langevin — estocástica, termodinamicamente fundamentada. No regime v3+ é a base da Dança Politemporal.

tópico em formalização, Equações de Langevin.

Lote / Loteria Joule

Lote: agrupamento de receipts em intervalos Langevin. Loteria Joule: protocolo pelo qual o sistema recompensa contribuições de poder computacional real, em ordem causal, com soma zero.

tópico em formalização.

LocalSyncDomain

Uma das 7 escalas fractais do Padrão Antropofágico (ver Auto-similaridade fractal): agrupamento de nós que compartilham um relógio Langevin e trocam CausalBlocks síncronamente. Corresponde à 6ª escala, entre o nó ABAPORU (5ª) e a malha global (7ª). Limites operacionais típicos: 3-50 nós, 1-100 km de raio, latência P99 < 50 ms.

Realidade fractal.


M

MacrophageVM

Sandbox WASM (rodando em wasmtime) onde pacotes suspeitos são fagocitados e analisados em profundidade. Sintetiza anticorpos.

tópico em formalização.

Maturidade Causal

Propriedade de um evento: ele “amadureceu” quando todos os seus dependentes causais também amadureceram. Ordenação por DVV, não por relógio. Em partições longas, a “idade causal” diverge da “idade cronológica” — é por design.

tópico em formalização, M/M/1 modelagem.

ML-DSA (Module-Lattice-Based Digital Signature Algorithm)

Assinatura digital pós-quântica (FIPS 204). Default em receipts e autenticação mútua. Antes: ML-DSA-65.

tópico em formalização.

ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism)

Encapsulamento de chaves pós-quântico (FIPS 203). Usado em sessão inicial entre dois nós.

MuleNode / MuleReceipt

MuleNode: nó de borda de recursos extremamente limitados (LoRa SX1262, ATmega, ESP32 em modo sleep profundo) que serve como ponte offline entre ilhas de autonomia. Não mantém DVV completo; acumula receipts locais e sincroniza em lote quando encontra outro nó (“mula” carregando dados). Sincroniza via protocolo Pororoca Causal — batched, eventual, com receipts imutáveis (cada batch emite um MuleReceipt resumido).

BC C.A.P.I.B.A., MANIFESTO § Soberania por Design.

MUS (Minimum Useful Survival)

Limiar de maturidade causal abaixo do qual um CausalBlock é candidato à apoptose saudável. Quando a Maturidade Causal de um bloco cai abaixo de MUS e sua taxa de novas interações $\Delta C \to 0$, o bloco evapora (a Landauer Gate decide o destino final). Parâmetro ajustável por nó, com mínimo absoluto garantido pelo Dicionário.

BC C.A.P.I.B.A..


O

Oceano

Camada de armazenamento fria, off-line, eventualmente consistente, para dados com $\Delta C \to 0$. Não serve plas quentes — apenas auditoria e reconstrução pós-morte.

BC C.A.P.I.B.A., R009 · Migração para Oceano.


P

Plasmídeo (DSL → WASM)

Unidade de código de contrato. Definido em TOML/HCL, compilado pelo paebiru-plasmids para um módulo WASM, executado em wasmtime dentro de uma membrana C.A.P.I.B.A.

tópico em formalização, DSL de Plasmídeos.

Pulse (Pulso)

Mensagem metabólica de homeostase trocada entre nós PAEBIRU, definida em crates/kernel/src/ports/mod.rs:31-36 como o enum MetabolicMessage::{PulseRequest, PulseResponse}. Funções canônicas:

  1. Sinal de vida (heartbeat) — emitido periodicamente (período padrão de 10s, configurável via DEFAULT_PULSE_PERIOD em apps/node/src/lib.rs).
  2. Atualização de saúde — cada PulseResponse carrega um health: f32 ∈ [0.0, 1.0] que alimenta o PeerHealth no Metabolism (ver BC Kernel) e, em última instância, o AlgedonicSensor local.
  3. Re-sincronização causal — em nós congelados, dispara avanço do Langevin Tick (ver R008 · Langevin Clock Drift).
  4. Anúncio na malha — ao ser publicado, o nó se torna visível para os peers no mesh gossipsub.

Transporte: gossipsub (tópico paebiru-metabolism). Descoberta dos pares: mDNS (LAN) + Kademlia DHT (global, via PAEBIRU_BOOTNODES). O pulso não é armazenado na DHT — ele flui ponto-a-ponto sobre conexões estabelecidas via descoberta.

Gate F1 do Roadmap: “dois nós trocam pulse ponta-a-ponta via libp2p Kademlia” — o critério de aceite do relé DHT é a troca de PulseRequest/PulseResponse ponta-a-ponta. BC Kernel, Hello, mesh.

Pororoca Causal

Protocolo de sincronização batched usado por MuleNodes (LoRa, ATmega) para reconciliar DVV e CausalBlocks entre ilhas de autonomia sem WAN contínua. O nome alude à pororoca (onda de maré que percorre o rio Amazonas contra a corrente): os dados viajam “contra” a partição de rede, em pulsos agregados, até encontrar um nó on-line. Cada pulso emite um MuleReceipt resumido e assinado.

BC C.A.P.I.B.A..

PoL (Proof of Location)

Prova de localização física preservando privacidade das coordenadas exatas. Construída via zk-SNARK Groth16.

tópico em formalização, R010 · Falha de ZK-PoL.

Portão / Gate

Cada um dos 5 estágios do ZeroTrustPipeline. Cada portão é opcionalmente desabilitável em dev via env var (PAEBIRU_SKIP_PF, etc.) — nunca em produção.

Prolly Tree

Árvore B+ com hashes determinísticos nos nós. Usada em C.A.P.I.B.A. para diffs pequenos em updates grandes.

tópico em formalização.


Q

Quórum adaptativo

Número mínimo de validadores para um receipt ser considerado final. Adapta-se ao tamanho da malha e à distância causal.

tópico em formalização.


R

Realidade fractal

Ver Auto-similaridade fractal.

Realidade fractal.

Recibo Soberano

Ver DRE.

Runbook vivo

Documento operacional que aprende com postmortems: cada incidente gera um patch no runbook correspondente. Versionado por git tag (runbook-vN).

tópico em formalização.


S

SPHINCS+

Assinatura pós-quântica stateless (FIPS 205). Usada como fallback do ML-DSA em cenários de limitação severa de banda.

Soberania

Princípio e estado: identidade enraizada em hardware, sem CA externo. Soberania é arquitetural, não contratual.

Sovereignty Gate

Portão de auditoria que todo CausalBlock deve atravessar antes de descer para o Oceano (cold storage). Combina três verificações: (1) CDDL — o bloco respeita o schema de dados contratado; (2) validação semântica — a carga é coerente com o tipo declarado; (3) ZK-PoL se houver dados de geolocalização. Falha em qualquer um = quarentena (MacrophageVM) + Recibo Soberano de verdict=reject.

BC C.A.P.I.B.A. · Princípios.


T

TPM (Trusted Platform Module)

Chip de silício que custodia chaves e atesta a integridade do firmware. Padrão para identidade soberana em nós com recursos suficientes.

R002 · Identidade TPM.


V

Veto Algedônico

Ação pela qual o hardware se sobrepõe a decisões de governança ao detectar dano físico iminente (temperatura > limiar, voltagem < mínimo, brown-out). Veto é local, imediato, e não negociável.

tópico em formalização.

Convenção editorial: grafia sempre em Title Case — Veto Algedônico (substantivo próprio), mesmo em meio de frase. A forma minúscula veto algedônico é reservada a citações textuais.

Voto Quadrático

Mecanismo de governança DAO em que o custo de um voto cresce quadraticamente com o número de votos que um agente emite sobre o mesmo tema: $C(n) = n^2$. Isso desencorrega plutocracia de whales e recompensa stake distribuído. Usado no PAEBIRU para decisões de protocolo que afetam toda a malha (mudança de parâmetros MUS, alteração de topologia default, ativação de novos plasmídeos canônicos).

View · Governança, tópico em formalização.


Z

ZeroTrustPipeline

Cadeia de 5 portões que todo pacote deve atravessar:

  1. Load Shedder (eBPF/XDP)
  2. Proof-of-Work (BLAKE3 salt + nonce)
  3. Assinatura ML-DSA
  4. ZK-PoL (Groth16)
  5. Contrato de Dados (CDDL)

tópico em formalização.

ZK-PoL

Ver PoL.


Apêndice — Siglas invertidas

SiglaForma canônicaBC / Crate
ABAPORUAgente BDIbiology
C.A.P.I.B.A.Causal, Asynchronous, Persistent, Immutable Block Architecturecapiba
CDDLConcise Data Definition Languagekernel
DREDistributed Receipt Engineeconomy
DVVDotted Version Vectorcapiba
eBPFExtended Berkeley Packet Filterkernel
FedAvgFederated Averaginglearn
FLAIRFederated Learning with AI-driven Rewardslearn
FROSTFlexible Round-Optimized Schnorr Thresholdkernel
GALSGlobally Asynchronous, Locally Synchronous(transversal)
HALHardware Abstraction Layerhal
ML-DSAModule-Lattice-Based DSAkernel
ML-KEMModule-Lattice-Based KEMkernel
PoLProof of Locationzk
SNNSpiking Neural Networkbiology
WASIWebAssembly System Interfaceplasmids
XDPeXpress Data Pathkernel
ZKZero-Knowledgezk

Política editorial

  • Adições e mudanças substantivas exigem uma RFC (Standards Track ou Experimental) com aprovação de pelo menos um maintainer.
  • Termos em inglês são aceitos quando consagrados pelo uso (ex: “GossipSub”); caso contrário, usar pt-BR.
  • Conflitos com código ou comentários devem ser corrigidos no código, mantendo este dicionário como fonte.

📊 Benchmarks de Performance

Resultados automáticos da última execução do cargo bench.

Gerado automaticamente em: Mon Jun 8 22:02:08 UTC 2026

BenchmarkTempo MédioUnidade
actor_handle_incoming_message105.42ns
handle_pulse_request25.530ns
handle_pulse_response25.645ns
handle_pulse_request_with_32_peers25.524ns
get_current_pressure311.63µs

🧮 Fundações matemáticas

O PAEBIRU é um sistema distribuído termodinamicamente fundamentado. Esta página é o índice das ferramentas matemáticas que sustentam os principais protocolos. As provas formais vivem em crates/*/formal/ (TLA+ para concorrência, Lean 4 para pureza).


Sumário

  1. Equações de Langevin
  2. Hamiltoniano de Ising
  3. Reed-Solomon sobre Corpos de Galois
  4. Dotted Version Vectors (DVV)
  5. Fórmula de Haversine
  6. Análise Topológica de Dados (TDA)
  7. Backpressure M/M/1
  8. Groth16 (zk-SNARKs)
  9. Verificação formal

Equações de Langevin

A dinâmica de Langevin governa o “tempo” do PAEBIRU:

$$ m , \frac{dv}{dt} = -\gamma v + \sqrt{2D} , \xi(t) + F_{\text{ext}} $$

SímboloSignificado
$m$“massa” do nó (1 para todos, em Langevin Ticks)
$\gamma$atrito termodinâmico (custo algedônico)
$D$difusão entrópica
$\xi(t)$ruído branco gaussiano
$F_{\text{ext}}$força externa (input da malha)

Implicação para o scheduler: um Langevin Tick só avança quando a entropia local varia ($\Delta S \neq 0$). Sem variação, o sistema “congela” — por isso o regime v3+ chama-se Dança Politemporal (tópico em formalização; ainda sem número de RFC atribuído, conforme a regra de ouro do processo).

Modelo formal em Lean 4: crates/paebiru-math/formal/lean/Langevin.lean.


Hamiltoniano de Ising

Usado pelo scheduler de enxame e pelo consenso bizantino adaptativo. Modelo $N$ spins em rede $d$-dimensional:

$$ \mathcal{H} = -J \sum_{\langle i,j \rangle} s_i s_j - h \sum_i s_i, \quad s_i \in {-1, +1} $$

Onde:

  • $J$ = acoplamento (positivo: ferromagnético; negativo: vidro de spin).
  • $h$ = campo externo (urgência do scheduler).
  • $\langle i, j \rangle$ = pares de vizinhos na malha.

O Ising solver (Fase 4) usa annealing simulado em paebiru-math para encontrar configurações de baixa energia — mapeando “tarefas” para “spins” e “custo” para “acoplamento”.


Reed-Solomon sobre Corpos de Galois

Usado em C.A.P.I.B.A. para reconstrução de blocos perdidos e correção de erros no WAL distribuído.

Dado mensagem $m = (m_0, \ldots, m_{k-1})$ em $\mathrm{GF}(2^8)$:

  1. Codifica em polinômio $p(x) = m_0 + m_1 x + \cdots + m_{k-1} x^{k-1}$.
  2. Avalia em $n$ pontos ($\mathrm{GF}(2^8)^* \cup {0}$).
  3. Distribui $n$ símbolos; recupera com $k \leq n’ < n$ (decodificação de Berlekamp-Welch ou Sugiyama).

Por que RS, não LDPC? O custo de decodificação em MCUs é proibitivo para LDPC; RS é tabelável em ROM de 2 kB.

Prova formal em Lean 4: crates/paebiru-math/formal/lean/ReedSolomon.lean.


Dotted Version Vectors (DVV)

Um DVV é um mapeamento de identificadores de evento para contadores, estendendo Causal Version Vectors com a noção de “discrete snapshot”.

$$ D_v : \text{EventId} \to \mathbb{N}, \quad D_v(\text{evento}) = \text{contador no produtor} $$

  • $D_v \sqsubseteq D_w$ significa “DVV $v$ é causalmente anterior a $D_w$”.
  • União por componente: $D_v \sqcup D_w$ é o least upper bound.
  • Maturidade Causal de um evento $e$ é a condição $D_e \sqsubseteq D_{\text{local}}$, isto é, todos os seus dependentes foram observados localmente.

tópico em formalização — referência normativa.


Fórmula de Haversine

Distância geodésica entre dois pontos na esfera ($\oplus$ = Terra, raio $R = 6371{,}0088$ km):

$$ d = 2R \cdot \arcsin!\left(\sqrt{\sin^2!\left(\frac{\Delta\phi}{2}\right) + \cos\phi_1 \cos\phi_2 \sin^2!\left(\frac{\Delta\lambda}{2}\right)}\right) $$

Usada em:

  • PoL (ZK-PoL): circunscrição de raio garantido.
  • Scheduler de proximidade: priorizar peers geograficamente próximos em redes LoRa (limites de tempo de propagação).

Implementação no_std em paebiru-math::geo::haversine_distance. Prova formal em Lean 4: Haversine.lean.


Análise Topológica de Dados (TDA)

Usada para detectar mudança de regime no comportamento da malha (saturação, deriva, partição).

A ferramenta central é a homologia persistente: dada uma nuvem de pontos $(x_i) \in \mathbb{R}^d$, constrói-se uma família de complexos simpliciais (Vietoris-Rips) e computa-se a persistência de cada classe homológica ($\beta_0$, $\beta_1$).

  • Classes de vida longa → estrutura topológica real.
  • Classes de vida curta → ruído.

Em Rust, integração com rust_tda (Fase 4) ou com bindings para gudhi (Python).


Modelagem de filas M/M/1

Para dimensionar buffers, backpressure e latência do ZeroTrustPipeline.

Consulte queues-model.md para a derivação completa de Little, Pollaczek-Khinchine e o regime de Langevin adaptativo.


Groth16 (zk-SNARKs)

zk-SNARK de referência usado no ZK-PoL. Setup confiável $S$ produz:

  • Chave de prova: $\text{pk} \in \mathbb{G}_1^{n+l} \times \mathbb{G}_2^{n}$.
  • Chave de verificação: $\text{vk} \in \mathbb{G}_1 \times \mathbb{G}_2^2$.
  • Prova: $\pi \in \mathbb{G}_1 \times \mathbb{G}_2$.

Para o PoL, o circuito verifica: “a posição $p$ está dentro do disco de raio $r$ centrado em $c$, sem revelar $p$ nem $c$.”

Curvas alvo: BN254 (default) e BLS12-381 (Fase 4). Mais em BC ZK.


Verificação formal

A verificação formal do PAEBIRU é cirúrgica: TLA+ para concorrência e estado global, Lean 4 para pureza algorítmica.

ModeloOnde viveO que prova
GALS-livenesscrates/paebiru-kernel/formal/tla/gals.tlaprogresso dos atores em partição
DRE sum-zerocrates/paebiru-economy/formal/tla/dre.tlainvariante de balanço
ZK-PoL soundnesscrates/paebiru-zk/formal/tla/pol.tlacompletude e solidez
Haversine no_stdcrates/paebiru-math/formal/lean/Haversine.leanprecisão geodésica
Reed-Solomoncrates/paebiru-math/formal/lean/ReedSolomon.leancorreção ≤ $\lfloor (n-k)/2 \rfloor$
Isingcrates/paebiru-math/formal/lean/Ising.leanannealing monotônico
Langevincrates/paebiru-math/formal/lean/Langevin.lean$\Delta t \propto \Delta S / \gamma$
Mutual creditformal/lean/MutualCredit.leansoma zero contínua

Acionada por make verify-formal.


Veja também

📊 Modelagem de Filas (M/M/1)

O PAEBIRU utiliza a teoria das filas para dimensionar o ZeroTrustPipeline e o sistema de Backpressure. O modelo M/M/1 serve como aproximação para o processamento de mensagens em um único nó.


1. Definições

  • λ (Lambda): Taxa média de chegada de mensagens (mensagens/seg).
  • μ (Mu): Taxa média de serviço do nó (mensagens/seg).
  • ρ (Rho): Intensidade de tráfego ($\rho = \lambda / \mu$).

2. Invariantes de Performance

Para manter a estabilidade metabólica, o nó deve operar em $\rho < 1$.

  • Tempo Médio no Sistema ($W$): $W = 1 / (\mu - \lambda)$.
  • Número Médio de Mensagens no Sistema ($L$): $L = \lambda / (\mu - \lambda)$.

3. Regime de Langevin Adaptativo

Quando $\rho \to 1$, o sensor algedônico dispara o sinal de dor, reduzindo $\lambda$ através da emissão de tokens de backpressure. No regime v3+ (Dança Politemporal), isso causa a dilatação do tempo local para permitir que o nó processe o acúmulo de mensagens sem dissipar calor excessivo.


4. Aplicação no ZeroTrustPipeline

Cada portão (1 a 5) atua como um servidor em uma fila serial. A latência total é a soma das latências de cada portão: $$T_{total} = \sum_{i=1}^{5} \frac{1}{\mu_i - \lambda}$$


5. Veja também

🧩 Padrões e Receitas

Lista de padrões arquiteturais e algoritmos recorrentes no ecossistema PAEBIRU.


1. Padrão Antropofágico (Fractal)

O ciclo ingerir → metabolizar → excretar deve ser aplicado em todas as escalas. Se você está criando um novo subsistema, ele deve ter:

  • Uma entrada de dados/eventos.
  • Um loop de processamento (metabolismo).
  • Uma saída de resultados/recibos.
  • Um sensor algedônico local.

2. Receptor-Reator

Nenhum componente deve agir de forma proativa sem um estímulo. Todo processamento é uma reação a um pulso metabólico ou mensagem de rede, garantindo que o sistema economize energia quando não há demanda.


3. Opaque Handles (FFI)

Nunca exponha tipos Rust complexos em bindings. Use ponteiros *mut c_void e funções de acesso para garantir que a memória seja gerida de forma segura e que o layout interno dos structs possa mudar sem quebrar os SDKs.


4. Veja também

🛠️ CLI do Forge

A CLI do Forge (paebiru) é a interface primária para gerenciar nós, identidades e plasmídeos.


1. Comandos de Nó

ComandoDescrição
paebiru node startInicia o daemon do nó.
paebiru node stopPara o nó graciosamente.
paebiru node statusExibe saúde, peers e backpressure.
paebiru node peersLista todos os peers na vizinhança causal.

2. Comandos de Identidade

ComandoDescrição
paebiru identity genGera uma nova identidade soberana.
paebiru identity showExibe o PeerID e chaves públicas.
paebiru identity importImporta uma identidade existente.
paebiru identity rotateInicia cerimônia FROST de rotação.

3. Comandos de Plasmídeo

ComandoDescrição
paebiru plasmid build <file>Compila a DSL para WASM.
paebiru plasmid sign <file>Assina um plasmídeo binário.
paebiru plasmid inject <id>Injeta o plasmídeo no nó local.
paebiru plasmid listLista plasmídeos ativos no nó.

4. Variáveis de Ambiente

VariávelPadrãoDescrição
PAEBIRU_STORAGE_PATH~/.paebiruOnde os dados e identidades são salvos.
PAEBIRU_API_PORT1975Porta do servidor HTTP de observabilidade.
RUST_LOGinfoNível de verbosidade dos logs.

5. Veja também

🧬 DSL de Plasmídeos

A DSL (Domain Specific Language) do PAEBIRU permite definir lógica de governança e computação de forma declarativa, que é então compilada para WebAssembly (WASM).


1. Estrutura do Arquivo (.toml / .hcl)

Um plasmídeo é definido por metadados e comportamentos:

[plasmid]
name = "meu-contrato"
version = "1.0.0"

[behavior]
on_init = "state.count = 0"
on_message = """
    if message.type == "increment" {
        state.count += 1
    }
"""

2. Tipos de Dados Suportados

  • Inteiros: i32, i64, u32, u64.
  • Decimais: f32, f64.
  • Booleanos: bool.
  • Coleções: Map, List (mapeados para heapless no WASM).

3. APIs Disponíveis (Host Calls)

O plasmídeo interage com o nó através de funções seguras:

  • log::info(msg): Emite logs para o nó host.
  • network::send(target, msg): Envia mensagens para outros nós.
  • storage::get(key): Recupera estado persistente do C.A.P.I.B.A.
  • entropy::now(): Obtém o Langevin Tick atual.

4. Segurança e Restrições

  • Determinismo: Plasmídeos não podem acessar o tempo do sistema ou números aleatórios não-determinísticos.
  • Gas/Metering: Cada instrução WASM consome créditos no LandauerLedger.
  • Isolamento: Não há acesso ao sistema de arquivos ou rede direta (apenas via host calls).

5. Veja também

📜 HCL (HashiCorp Configuration Language)

O PAEBIRU utiliza HCL como uma alternativa ao TOML para a definição de plasmídeos complexos e orquestração de infraestrutura de névoa.


1. Por que HCL?

HCL oferece maior flexibilidade para configurações hierárquicas e suporte nativo a interpolação de variáveis, o que é útil para definir comportamentos de plasmídeos que dependem de condições de hardware específicas.


2. Exemplo de Definição de Nó

node "edge-01" {
  storage_path = "/var/lib/paebiru"
  api_port     = 1975

  sensor "temperature" {
    threshold_pain = 75.5
  }
}

plasmid "monitor" {
  version = "1.2.0"
  capabilities = ["network", "storage"]
}

3. Veja também

🔌 WASI-PAEBIRU ABI

A ABI (Application Binary Interface) define o contrato de baixo nível entre o host (nó PAEBIRU) e o guest (módulo WASM/Plasmídeo). Ela estende o padrão WASI para suportar as necessidades específicas de sistemas distribuídos soberanos.


1. Convenções de Memória

  • Linear Memory: O guest e o host compartilham um buffer de memória linear.
  • Opaque Handles: Referências a recursos complexos (canais de rede, instâncias de banco) são passadas como handles inteiros de 32 bits.
  • Zero-Copy: Estruturas grandes são passadas via ponteiro e tamanho, evitando serialização pesada (Dogma 4).

2. Importações de Host (Host Imports)

Funções que o módulo WASM pode invocar:

#![allow(unused)]
fn main() {
// Exemplo de assinatura na Camada 9
extern "C" {
    fn paebiru_send_message(target_ptr: *const u8, msg_ptr: *const u8, msg_len: usize) -> i32;
    fn paebiru_get_causal_tick() -> u64;
    fn paebiru_log_event(level: i32, msg_ptr: *const u8, msg_len: usize);
}
}

3. Exportações de Guest (Guest Exports)

Funções que o nó host invoca no plasmídeo:

  • paebiru_init(): Chamada ao carregar o plasmídeo.
  • paebiru_process_message(sender_id, msg_id): Chamada para reagir a estímulos da malha.
  • paebiru_shutdown(): Chamada antes de descarregar o módulo.

4. Tratamento de Erros

A ABI utiliza códigos de retorno inteiros:

  • 0: Sucesso.
  • < 0: Erros de sistema (ex: -1 = Out of Memory, -2 = Permission Denied).
  • > 0: Erros específicos do domínio do plasmídeo.

5. Veja também

🔌 SDKs e bindings

O PAEBIRU é escrito em Rust, mas é interoperável com 13 linguagens via bindings canônicos. Esta trilha documenta o design assíncrono comum e cada binding individualmente.

Princípios

  • Opaque handles + zero-copy — nenhum binding expõe tipos internos do Kernel; serialização pesada é evitada na Camada 9 (tópico em formalização).
  • API síncrona-para-async — bindings para linguagens síncronas (C, PHP, R, Lua) expõem wrappers que internamente despacham para o runtime tokio via thread pool.
  • Capacidades, não tipos — o binding expõe capabilities (ler, assinar, votar), não structs internos.

Visão geral

BindingCrateTecnologiaEstabilidade
Cpaebiru-cFFI nativo🟢 Estável
Pythonpaebiru-pyPyO3🟡 Beta
TypeScript/WASMpaebiru-tswasm-bindgen🟡 Beta
Gopaebiru-goCGO🟡 Beta
Javapaebiru-javaJNI🟡 Beta
C#paebiru-csharpP/Invoke🟠 Alfa
Dartpaebiru-dartFFI🟠 Alfa
Swiftpaebiru-swiftUniFFI🟠 Alfa
Rubypaebiru-rubyMagnus🟠 Alfa
PHPpaebiru-phpext-php-rs🟠 Alfa
Luapaebiru-luamlua🟠 Alfa
Rpaebiru-rextendr🟠 Alfa
Zig(via paebiru-c)FFI🟠 Alfa

Não use bindings em produção durante a Fase 1 — apenas paebiru-c é considerado estável, e mesmo assim em modo “laboratório”.

Páginas

Veja também

🌀 Design Assíncrono

O PAEBIRU é assíncrono por natureza. Este documento descreve como o modelo de concorrência do Rust (Tokio) é mapeado para as diferentes linguagens suportadas.


1. O Loop de Eventos do Kernel

Toda instância do PAEBIRU roda um runtime Tokio internamente. Mesmo em linguagens síncronas, as operações de rede e IO ocorrem em threads de background geridas pelo Rust.


2. Mapeamento por Linguagem

Linguagens Modernas (Async-Native)

  • Rust/Python/TS/Go/Dart/Swift/C#: O SDK expõe funções async ou que retornam Promises/Futures. O runtime da linguagem aguarda o sinal do kernel Rust.

Linguagens Síncronas (Thread-Based)

  • C/PHP/Ruby/Lua/R: O SDK fornece chamadas bloqueantes que, por baixo dos panos, despacham a tarefa para o runtime Rust e aguardam a conclusão via variável de condição (CondVar) ou polling.

3. Callbacks e Eventos

As mensagens vindas da malha (GossipSub) são entregues através de um sistema de subscrição:

  1. O usuário registra um handler no SDK.
  2. O Kernel Rust recebe a mensagem e a coloca em uma fila de despacho.
  3. O SDK “puxa” a mensagem ou invoca o callback no contexto da linguagem alvo.

4. Veja também

📦 Guia de Release

Políticas de versionamento, estabilidade e compatibilidade para os SDKs e Bindings do PAEBIRU.


1. Versionamento Semântico (SemVer)

Seguimos rigorosamente o SemVer 2.0.0 para todos os crates e pacotes de linguagem:

  • Major: Quebra de compatibilidade na ABI ou APIs públicas.
  • Minor: Novas funcionalidades compatíveis.
  • Patch: Correções de bugs e segurança.

2. Matriz de Estabilidade

NívelSignificadoExemplo
🟢 EstávelAPI congelada, garantias de compatibilidade por 12 meses.paebiru-c
🟡 BetaFuncional, mas APIs podem sofrer ajustes menores.paebiru-py, paebiru-ts
🟠 AlfaExperimental, uso apenas para laboratório/feedback.paebiru-dart, paebiru-lua

3. Política de Depreciação

Mudanças que quebram a API devem passar por um ciclo de depreciação de pelo menos uma versão Minor, emitindo warnings em tempo de compilação ou execução antes da remoção final.


4. Ciclo de Publicação

As releases dos SDKs são sincronizadas com as tags do repositório principal. O pipeline de CI automatiza a publicação para os gestores de pacotes (PyPI, npm, Maven, etc.) assim que uma tag v* é criada.


5. Veja também

🔌 C (paebiru-c)

O binding C é a base de todos os outros 24 bindings do PAEBIRU. Cada binding — seja Java via JNI, C# via P/Invoke, Python via PyO3, ou Zig via @cImport — consome paebiru-c como contrato canônico da API do Kernel. Manter este header estável, documentado e ABI-compatível é a maior responsabilidade do projeto: qualquer quebra aqui quebra todos os 24 outros bindings simultaneamente.

O binding usa C puro (C11+) com extern "C" guards para compatibilidade com C++, segue convenções POSIX/Linux-friendly (size_t, ssize_t, uint32_t), e implementa o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com ponteiros opacos (paebiru_node_t*), ownership explícito (caller chama _destroy), e zero-cópia via ponteiro direto para buffers do chamador.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via forward-declared structs: instâncias nativas (nó, identidade, recibo) são representadas como typedef struct paebiru_node_s paebiru_node_t; com apenas forward declaration no header público — o layout interno fica escondido na .so/.a. O usuário sempre passa paebiru_node_t* (ponteiro opaco) entre funções.
  • Convenção de nomenclatura:
    • Todas as funções e tipos começam com paebiru_ para evitar poluição de namespace global.
    • Funções em snake_case (paebiru_node_create, paebiru_node_send_message).
    • Tipos em snake_case com sufixo _t (paebiru_node_t, paebiru_receipt_t) — convenção POSIX.
    • Erros em paebiru_error_t enum ou retornando int (negativo em erro, 0 em sucesso) — int é mais simples para ABI stability.
    • Macros e constantes em UPPER_SNAKE_CASE com prefixo PAEBIRU_ (PAEBIRU_DEFAULT_PORT, PAEBIRU_MAX_PLASMID_SIZE).
  • Gerenciamento de memória — ownership explícito: o caller é responsável por destruir os handles criados (paebiru_node_destroy(handle)). Não há garbage collection, reference counting, ou cleanup implícito. Lifespan contracts estão documentados em cada função.
  • Distribuição: libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows) — empacotada via pkg-config, vcpkg, Conan, ou como target CMake find_package(paebiru). Header paebiru.h em /usr/local/include/paebiru/.
  • ABI compatibility: o header segue o Itanium C++ ABI (também usado por Itanium/System V para C). Funções decoradas com __attribute__((visibility("default"))) em GCC/Clang; equivalentes MSVC via __declspec(dllexport).
  • Thread-safety: o Node é thread-safe para operações de leitura (paebiru_node_send_message, _poll_event), mas não para lifecycle (_create/_destroy devem ser chamados de uma única thread).
  • Zero-cópia via ponteiro direto: o caller passa const uint8_t* payload, size_t payload_len — o lado C não copia o buffer (a menos que precise). O caller deve garantir que o buffer vive durante a chamada.
  • Compatibilidade C++: #ifdef __cplusplus extern "C" { guard em torno de toda a API, permitindo que C++ consuma sem name mangling.
  • Determinismo temporal: funções críticas têm bound determinístico (ex: paebiru_node_poll_event retorna em ≤ 100 µs).
  • Atomicidade: paebiru_node_send_message é atômico — ou retorna recibo com sucesso, ou retorna erro sem efeito colateral.

2. Instalação

Via package manager do sistema

# Debian/Ubuntu
apt-get install libpaebiru-dev

# macOS
brew install paebiru

# Arch
pacman -S paebiru

# Windows (vcpkg)
vcpkg install paebiru:x64-windows

Via CMake find_package

# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(my_paebiru_app LANGUAGES C CXX)

find_package(paebiru 0.1 REQUIRED PATHS /usr/local/lib/cmake/paebiru)

add_executable(myapp main.c)
target_link_libraries(myapp PRIVATE paebiru::paebiru)
cmake -B build -DPAEBIRU_DIR=/usr/local
cmake --build build
./build/myapp

Via pkg-config

pkg-config --cflags --libs paebiru
# → -I/usr/local/include -L/usr/local/lib -lpaebiru
gcc main.c $(pkg-config --cflags --libs paebiru) -o myapp

Compilação manual (a partir do source)

git clone https://github.com/paebiru/paebiru-c.git
cd paebiru-c
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
sudo make install

Verificação

#include <paebiru.h>
#include <stdio.h>

int main(void) {
    printf("paebiru-c %d.%d.%d\n",
           paebiru_VERSION_MAJOR,
           paebiru_VERSION_MINOR,
           paebiru_VERSION_PATCH);
    return 0;
}
gcc -o check_paebiru check_paebiru.c $(pkg-config --cflags --libs paebiru)
./check_paebiru
# → paebiru-c 0.1.0

Dependências runtime

  • C11+ compiler: GCC ≥ 9, Clang ≥ 10, MSVC ≥ 2019
  • libc (sempre disponível)
  • libpthread (para threading) — linkado automaticamente
  • libdl (Linux, para dlopen/dlsym se necessário)
  • Sistema: libpaebiru.so / .dylib / .dll

3. Header paebiru.h — Contrato Completo

/* include/paebiru/paebiru.h
 *
 * Header público do binding C do PAEBIRU.
 * Este é o CONTRATO CANÔNICO consumido por todos os outros
 * 24 bindings do projeto. Mudanças aqui são breaking changes
 * para todos os bindings.
 *
 * Standard: C11 + GNU extensions (GCC/Clang) ou MSVC extensions
 * License: AGPL-3.0-or-later
 */

#ifndef PAEBIRU_H
#define PAEBIRU_H

#include <stddef.h>     /* size_t, NULL */
#include <stdint.h>     /* uint8_t, uint32_t, uint64_t, int32_t */
#include <stdbool.h>    /* bool, true, false */
#include <sys/types.h>  /* ssize_t (POSIX) */

#ifdef __cplusplus
extern "C" {
#endif

/* =================================================================
 * Versioning
 * ================================================================= */

#define PAEBIRU_VERSION_MAJOR 0
#define PAEBIRU_VERSION_MINOR 1
#define PAEBIRU_VERSION_PATCH 0

/* Compile-time version check (use in application code) */
#if defined(PAEBIRU_REQUIRE_VERSION)
  #if (PAEBIRU_VERSION_MAJOR << 16 | PAEBIRU_VERSION_MINOR << 8 | \
       PAEBIRU_VERSION_PATCH) < PAEBIRU_REQUIRE_VERSION
    #error "paebiru-c version too old; please upgrade"
  #endif
#endif

/* Runtime version (callers can check API compatibility) */
const char* paebiru_version_string(void);
uint32_t paebiru_version_compat(void);  /* 0x00MMmmpp */

/* =================================================================
 * Error codes (returned by all paebiru_* functions)
 * ================================================================= */

typedef enum paebiru_error_e {
    PAEBIRU_OK              =  0,  /* Success */
    PAEBIRU_ERR_INVALID_ARG = -1,  /* Invalid argument */
    PAEBIRU_ERR_OUT_OF_MEMORY = -2,/* malloc/realloc failed */
    PAEBIRU_ERR_NETWORK     = -3,  /* Network error */
    PAEBIRU_ERR_IO          = -4,  /* File I/O error */
    PAEBIRU_ERR_TIMEOUT     = -5,  /* Operation timed out */
    PAEBIRU_ERR_NOT_FOUND   = -6,  /* Resource not found */
    PAEBIRU_ERR_ALREADY     = -7,  /* Already initialized */
    PAEBIRU_ERR_INTERNAL    = -100 /* Internal error (likely bug) */
} paebiru_error_t;

/* Returns human-readable description of an error code */
const char* paebiru_error_str(paebiru_error_t err);

/* =================================================================
 * Opaque types (forward-declared; layout is private)
 * ================================================================= */

typedef struct paebiru_node_s     paebiru_node_t;      /* Opaque node handle */
typedef struct paebiru_identity_s paebiru_identity_t;  /* Opaque identity */
typedef struct paebiru_receipt_s  paebiru_receipt_t;   /* Opaque receipt */
typedef struct paebiru_plasmid_s  paebiru_plasmid_t;   /* Opaque plasmid */
typedef struct paebiru_mesh_event_s paebiru_mesh_event_t; /* Opaque mesh event */

/* =================================================================
 * Constants
 * ================================================================= */

#define PAEBIRU_DEFAULT_PORT     1975
#define PAEBIRU_DEFAULT_PORT_STR "1975"

#define PAEBIRU_MAX_PEER_ID_LEN  128
#define PAEBIRU_MAX_CID_BYTES    32      /* BLAKE3 hash size */
#define PAEBIRU_MAX_CID_HEX_LEN  64      /* 2 * MAX_CID_BYTES, no null */
#define PAEBIRU_MAX_PAYLOAD_SIZE (16 * 1024 * 1024)  /* 16 MB */
#define PAEBIRU_MAX_PLASMID_SIZE (8 * 1024 * 1024)   /* 8 MB */

/* Event types (for paebiru_mesh_event_t) */
typedef enum paebiru_event_type_e {
    PAEBIRU_EVENT_NONE              = 0,
    PAEBIRU_EVENT_PEER_CONNECTED    = 1,
    PAEBIRU_EVENT_PEER_LOST         = 2,
    PAEBIRU_EVENT_RECEIPT_PRODUCED  = 3,
    PAEBIRU_EVENT_ALGEDONIC         = 4
} paebiru_event_type_t;

/* =================================================================
 * Node lifecycle
 * ================================================================= */

/* Create a new PAEBIRU node.
 *
 * @param storage_path  Directory for node storage (must exist, writable).
 * @return              Opaque handle on success, NULL on error.
 * @error               PAEBIRU_ERR_INVALID_ARG, PAEBIRU_ERR_OUT_OF_MEMORY
 *
 * @lifespan            Handle must be destroyed via paebiru_node_destroy.
 * @thread-safety       NOT thread-safe; call from a single thread.
 */
paebiru_node_t* paebiru_node_create(const char* storage_path);

/* Start the node (begins network discovery, listening, etc.).
 *
 * @param node          Handle from paebiru_node_create.
 * @return              PAEBIRU_OK on success, negative on error.
 * @error               PAEBIRU_ERR_ALREADY, PAEBIRU_ERR_NETWORK
 *
 * @lifespan            Until paebiru_node_stop.
 * @thread-safety       NOT thread-safe with destroy.
 */
paebiru_error_t paebiru_node_start(paebiru_node_t* node);

/* Stop the node gracefully (finishes pending operations).
 *
 * @param node          Handle.
 * @return              PAEBIRU_OK on success.
 *
 * @thread-safety       NOT thread-safe.
 */
paebiru_error_t paebiru_node_stop(paebiru_node_t* node);

/* Destroy the node and free all associated resources.
 *
 * @param node          Handle. NULL-safe (no-op if node == NULL).
 *
 * @lifespan            After this call, the handle is INVALID.
 * @thread-safety       NOT thread-safe; do not call concurrent with other ops.
 */
void paebiru_node_destroy(paebiru_node_t* node);

/* =================================================================
 * Messaging
 * ================================================================= */

/* Send a message to a target peer and wait for the Receipt.
 *
 * @param node          Handle (must be started).
 * @param target        Peer ID (null-terminated C string, max 127 chars).
 * @param target_len    strlen(target) — caller passes for zero-copy.
 * @param payload       Pointer to payload bytes (zero-copy).
 * @param payload_len   Size of payload in bytes (0 .. MAX_PAYLOAD_SIZE).
 * @param receipt_out   Output: filled with Receipt on success.
 * @return              PAEBIRU_OK on success, negative on error.
 *
 * @lifespan            payload buffer must remain valid during the call.
 *                     receipt_out is filled synchronously.
 * @thread-safety       SAFE for concurrent calls from multiple threads.
 */
paebiru_error_t paebiru_node_send_message(
    paebiru_node_t*       node,
    const char*           target,
    size_t                target_len,
    const uint8_t*        payload,
    size_t                payload_len,
    paebiru_receipt_t*    receipt_out
);

/* Send a message asynchronously (returns immediately).
 *
 * @param node          Handle.
 * @param target        Peer ID.
 * @param target_len    strlen(target).
 * @param payload       Pointer to payload (zero-copy during call).
 * @param payload_len   Size of payload.
 * @param user_data     Opaque pointer passed to completion callback.
 * @param callback      Function called with receipt (or NULL on error).
 * @return              PAEBIRU_OK if accepted; negative if queue full.
 *
 * @thread-safety       SAFE for concurrent calls.
 */
typedef void (*paebiru_send_completion_fn)(
    paebiru_error_t       status,
    paebiru_receipt_t*    receipt,
    void*                 user_data
);

paebiru_error_t paebiru_node_send_message_async(
    paebiru_node_t*             node,
    const char*                 target,
    size_t                      target_len,
    const uint8_t*              payload,
    size_t                      payload_len,
    void*                       user_data,
    paebiru_send_completion_fn  callback
);

/* =================================================================
 * Event polling
 * ================================================================= */

/* Poll for the next mesh event (non-blocking).
 *
 * @param node          Handle.
 * @param event_out     Output: filled with event data on success.
 * @return              PAEBIRU_OK if event was returned, PAEBIRU_ERR_TIMEOUT
 *                     if no event available (event_out unchanged).
 *
 * @thread-safety       SAFE for concurrent calls (one event per call).
 *                     For high-throughput, use paebiru_node_subscribe.
 */
paebiru_error_t paebiru_node_poll_event(
    paebiru_node_t*         node,
    paebiru_mesh_event_t*   event_out
);

/* Extract event type, peer ID, and payload from event. */
paebiru_event_type_t paebiru_event_get_type(const paebiru_mesh_event_t* event);
const char*          paebiru_event_get_peer_id(const paebiru_mesh_event_t* event);
size_t               paebiru_event_get_peer_id_len(const paebiru_mesh_event_t* event);
const uint8_t*       paebiru_event_get_payload(const paebiru_mesh_event_t* event);
size_t               paebiru_event_get_payload_len(const paebiru_mesh_event_t* event);
const paebiru_receipt_t* paebiru_event_get_receipt(const paebiru_mesh_event_t* event);

/* =================================================================
 * Receipt operations
 * ================================================================= */

/* Get CID (32 bytes raw). */
const uint8_t* paebiru_receipt_get_cid(const paebiru_receipt_t* receipt);

/* Get CID as 64-char lowercase hex (null-terminated, 65 bytes including NUL). */
const char* paebiru_receipt_get_cid_hex(const paebiru_receipt_t* receipt);

/* Get cost in micro-joules. */
uint64_t paebiru_receipt_get_micro_joules(const paebiru_receipt_t* receipt);

/* Get Algedonic health flag. */
bool paebiru_receipt_is_algedonically_healthy(const paebiru_receipt_t* receipt);

/* Get timestamp in nanoseconds since Unix epoch. */
uint64_t paebiru_receipt_get_timestamp_ns(const paebiru_receipt_t* receipt);

/* Compute the CausalBlock CID of arbitrary data (utility). */
paebiru_error_t paebiru_compute_cid(
    const uint8_t*  data,
    size_t          data_len,
    uint8_t         cid_out[PAEBIRU_MAX_CID_BYTES]
);

/* =================================================================
 * Status and metrics
 * ================================================================= */

typedef struct paebiru_node_status_s {
    bool        is_active;         /* started and not stopped */
    uint32_t    connected_peers;   /* count */
    uint64_t    total_messages_sent;
    uint64_t    total_messages_received;
    uint64_t    total_receipts_produced;
    double      cpu_usage_percent; /* 0.0 - 100.0 */
    double      memory_usage_mb;
} paebiru_node_status_t;

paebiru_error_t paebiru_node_get_status(
    paebiru_node_t*         node,
    paebiru_node_status_t*  status_out
);

#ifdef __cplusplus
}  /* extern "C" */
#endif

#endif /* PAEBIRU_H */

4. Exemplos Completos

Exemplo 1: Cliente síncrono

/* examples/sync_client.c */
#include <paebiru.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void) {
    paebiru_node_t* node = paebiru_node_create("./data");
    if (!node) {
        fprintf(stderr, "Failed to create node\n");
        return 1;
    }

    paebiru_error_t err = paebiru_node_start(node);
    if (err != PAEBIRU_OK) {
        fprintf(stderr, "Start failed: %s\n", paebiru_error_str(err));
        paebiru_node_destroy(node);
        return 1;
    }

    /* Envia mensagem */
    const char* target = "audit_mesh";
    const uint8_t payload[] = "hello from C";

    paebiru_receipt_t receipt;
    err = paebiru_node_send_message(
        node,
        target, strlen(target),
        payload, sizeof(payload) - 1,  /* exclui NUL */
        &receipt
    );
    if (err != PAEBIRU_OK) {
        fprintf(stderr, "Send failed: %s\n", paebiru_error_str(err));
    } else {
        printf("Receipt CID: %s\n", paebiru_receipt_get_cid_hex(&receipt));
        printf("Custo µJ:    %lu\n",
               (unsigned long) paebiru_receipt_get_micro_joules(&receipt));
        printf("Algedonic:   %s\n",
               paebiru_receipt_is_algedonically_healthy(&receipt) ? "OK" : "FAIL");
    }

    paebiru_node_stop(node);
    paebiru_node_destroy(node);
    return 0;
}

Exemplo 2: Polling loop multithreaded (com pthreads)

/* examples/poll_thread.c */
#define _POSIX_C_SOURCE 200809L
#include <paebiru.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

typedef struct {
    paebiru_node_t* node;
    volatile int    running;
} poll_ctx_t;

static void* poll_thread(void* arg) {
    poll_ctx_t* ctx = (poll_ctx_t*)arg;
    while (ctx->running) {
        paebiru_mesh_event_t event;
        paebiru_error_t err = paebiru_node_poll_event(ctx->node, &event);
        if (err == PAEBIRU_OK) {
            const char* peer_id = paebiru_event_get_peer_id(&event);
            size_t peer_len = paebiru_event_get_peer_id_len(&event);
            printf("[event] type=%d peer=%.*s\n",
                   paebiru_event_get_type(&event),
                   (int)peer_len, peer_id);
        } else if (err == PAEBIRU_ERR_TIMEOUT) {
            usleep(10000);  /* 10 ms backoff */
        } else {
            fprintf(stderr, "Poll error: %s\n", paebiru_error_str(err));
            break;
        }
    }
    return NULL;
}

int main(void) {
    paebiru_node_t* node = paebiru_node_create("./data");
    paebiru_node_start(node);

    poll_ctx_t ctx = { .node = node, .running = 1 };
    pthread_t tid;
    pthread_create(&tid, NULL, poll_thread, &ctx);

    /* Main thread: envia mensagens */
    for (int i = 0; i < 10; i++) {
        char payload[32];
        snprintf(payload, sizeof(payload), "msg #%d", i);
        paebiru_receipt_t r;
        paebiru_node_send_message(
            node, "audit_mesh", strlen("audit_mesh"),
            (const uint8_t*)payload, strlen(payload),
            &r
        );
        sleep(1);
    }

    ctx.running = 0;
    pthread_join(tid, NULL);
    paebiru_node_destroy(node);
    return 0;
}

Exemplo 3: C++ com RAII

// examples/cpp_raii.cpp
#include <paebiru.h>
#include <iostream>
#include <stdexcept>
#include <vector>
#include <string>

class PaebiruNode {
public:
    explicit PaebiruNode(const std::string& storage_path)
        : node_(paebiru_node_create(storage_path.c_str())) {
        if (!node_) throw std::runtime_error("paebiru_node_create failed");
    }

    ~PaebiruNode() {
        if (node_) {
            paebiru_node_stop(node_);
            paebiru_node_destroy(node_);
        }
    }

    PaebiruNode(const PaebiruNode&) = delete;
    PaebiruNode& operator=(const PaebiruNode&) = delete;

    void start() {
        auto err = paebiru_node_start(node_);
        if (err != PAEBIRU_OK)
            throw std::runtime_error(std::string("start failed: ") +
                                     paebiru_error_str(err));
    }

    std::vector<uint8_t> send_message(
        const std::string& target,
        const std::vector<uint8_t>& payload
    ) {
        paebiru_receipt_t receipt;
        auto err = paebiru_node_send_message(
            node_,
            target.c_str(), target.size(),
            payload.data(), payload.size(),
            &receipt
        );
        if (err != PAEBIRU_OK) {
            throw std::runtime_error(std::string("send failed: ") +
                                     paebiru_error_str(err));
        }
        return std::vector<uint8_t>(
            paebiru_receipt_get_cid(&receipt),
            paebiru_receipt_get_cid(&receipt) + PAEBIRU_MAX_CID_BYTES
        );
    }

private:
    paebiru_node_t* node_;
};

int main() {
    try {
        PaebiruNode node("./data");
        node.start();

        std::string target = "audit_mesh";
        std::vector<uint8_t> payload{'h', 'e', 'l', 'l', 'o'};
        auto cid = node.send_message(target, payload);

        std::cout << "Receipt CID: ";
        for (auto b : cid) printf("%02x", b);
        std::cout << "\n";
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << "\n";
        return 1;
    }
}

Exemplo 4: CMakeLists.txt

# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(my_paebiru_app LANGUAGES C CXX)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)  # Use C11 strict, not GNU extensions

# Find paebiru-c via find_package
find_package(paebiru 0.1 REQUIRED)

add_executable(sync_client examples/sync_client.c)
target_link_libraries(sync_client PRIVATE paebiru::paebiru)

add_executable(poll_thread examples/poll_thread.c)
target_link_libraries(poll_thread PRIVATE paebiru::paebiru pthread)

# C++ example with RAII
add_executable(cpp_raii examples/cpp_raii.cpp)
target_link_libraries(cpp_raii PRIVATE paebiru::paebiru)

# Tests
enable_testing()
add_executable(test_paebiru tests/test_paebiru.c)
target_link_libraries(test_paebiru PRIVATE paebiru::paebiru)
add_test(NAME paebiru COMMAND test_paebiru)

Exemplo 5: Testes com Unity

/* tests/test_paebiru.c */
#include "unity.h"
#include <paebiru.h>
#include <string.h>

void setUp(void) {}
void tearDown(void) {}

void test_version_string_is_not_empty(void) {
    const char* v = paebiru_version_string();
    TEST_ASSERT_NOT_NULL(v);
    TEST_ASSERT_GREATER_THAN(0, strlen(v));
}

void test_version_compat_matches_macros(void) {
    uint32_t v = paebiru_version_compat();
    TEST_ASSERT_EQUAL_HEX32(
        (PAEBIRU_VERSION_MAJOR << 16) |
        (PAEBIRU_VERSION_MINOR << 8)  |
         PAEBIRU_VERSION_PATCH,
        v
    );
}

void test_error_str_returns_valid_strings(void) {
    TEST_ASSERT_EQUAL_STRING("Success", paebiru_error_str(PAEBIRU_OK));
    TEST_ASSERT_EQUAL_STRING("Invalid argument", paebiru_error_str(PAEBIRU_ERR_INVALID_ARG));
    TEST_ASSERT_EQUAL_STRING("Out of memory", paebiru_error_str(PAEBIRU_ERR_OUT_OF_MEMORY));
}

void test_node_create_with_null_path_returns_null(void) {
    paebiru_node_t* n = paebiru_node_create(NULL);
    TEST_ASSERT_NULL(n);
}

void test_node_destroy_null_is_safe(void) {
    paebiru_node_destroy(NULL);  /* não deve crashar */
}

void test_send_message_with_invalid_args_returns_error(void) {
    paebiru_node_t* n = paebiru_node_create("./data");
    TEST_ASSERT_NOT_NULL(n);
    paebiru_receipt_t r;
    /* Sem start — deve falhar */
    paebiru_error_t err = paebiru_node_send_message(
        n, "peer", 4, (const uint8_t*)"x", 1, &r
    );
    TEST_ASSERT_NOT_EQUAL(PAEBIRU_OK, err);
    paebiru_node_destroy(n);
}

int main(void) {
    UNITY_BEGIN();
    RUN_TEST(test_version_string_is_not_empty);
    RUN_TEST(test_version_compat_matches_macros);
    RUN_TEST(test_error_str_returns_valid_strings);
    RUN_TEST(test_node_create_with_null_path_returns_null);
    RUN_TEST(test_node_destroy_null_is_safe);
    RUN_TEST(test_send_message_with_invalid_args_returns_error);
    return UNITY_END();
}

5. Veja também

🟦 C++ (paebiru-cpp)

O binding C++ é, entre os 25+ do projeto, o mais fundamental depois de C — C++ é a evolução direta de C (com classes, templates, RAII, move semantics) e domina domínios onde o PAEBIRU tem presença canônica: game engines (Unreal, Unity native plugins), high-frequency trading (HFT audit com latência sub-microsegundo), computer vision (OpenCV pipelines), sistemas embarcados (ROS2, drones, robôs), desktop GUI (Qt, wxWidgets), e engenharia de sistemas (Chromium, Firefox, Office, Unreal). C++ é também a única linguagem com ecossistema maduro de coroutines, modules, concepts, ranges, expected, e span — todas as features C++20/23 que permitem modelagem type-safe e zero-overhead.

O binding usa extern "C" para vincular paebiru-c (estabelecido em PR-25), e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com RAII para cleanup determinístico (deleters customizados chamam paebiru_node_destroy), std::span<std::byte const> para zero-copy de buffers, std::expected<T, Error> (C++23) para error handling sem exceções, e coroutines (C++20) para async event streams.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via std::unique_ptr<T, Deleter> com RAII: instâncias nativas (nó, identidade, recibo) são representadas por std::unique_ptr<opa::node, opa::node_deleter> com deleter customizado que chama paebiru_node_destroy no destrutor. Rule of Zero (sem destrutor custom, sem copy/move) — o smart pointer cuida de tudo.
  • Convenção de nomenclatura:
    • Classes, structs, enums em PascalCase (Node, Receipt, MeshEvent, Error).
    • Funções, métodos, variáveis em snake_case (send_message, storage_path, is_healthy).
    • Constantes em kebab-case dentro de inline constexpr namespace (estilo moderno): inline constexpr auto max_cid_bytes = 32;.
    • Membros privados com sufixo _ (estilo Google/Chromium) ou prefixo m_ (estilo Qt/Boost) — documentado como escolha do projeto.
    • Namespaces: paebiru para API pública, paebiru::detail para implementação.
    • Concepts: concept MeshEventHandler para duck typing.
  • Gerenciamento de memória (Rule of Zero): classes encapsulando handles C não declaram destrutor, constructor de cópia, move, ou assignment — deixam std::unique_ptr gerenciar tudo. Cleanup determinístico via RAII no escopo léxico.
  • Distribuição: pacote vcpkg (Windows/Linux/macOS), Conan 2 (cross-platform), ou header-only via FetchContent no CMake. Para header-only, é o binding mais leve para embutir.
  • Zero-cópia via std::span<std::byte const>: std::span é uma vista não-owning sobre memória contígua — passada para C sem cópia via reinterpret_cast<std::byte const*>. Compatível com std::vector, std::array, std::string_view, e raw pointers.
  • std::expected<T, Error> para error handling (C++23): análogo a Result<T, E> em Rust. Sem exceções, sem tratamento implícito — o caller deve inspecionar o resultado. Para C++20, use tl::expected (header-only).
  • Coroutines para async event streams (C++20): Generator<MeshEvent> Node::events() produz eventos via co_yield. Casa com ranges (C++20) e views (std::views::filter, std::views::take).
  • Modules para organização (C++20): export module paebiru; em paebiru.cppm substitui headers tradicionais com build times mais rápidos e melhor encapsulamento.
  • Concepts para type safety (C++20): template<typename T> concept Plasmable = ... permite verificação em compile-time sem SFINAE.
  • Thread-safety documentado (sem std::shared_mutex por padrão — o usuário escolhe o modelo de concorrência).
  • [[nodiscard]] em funções que retornam valor: previne discard acidental de Receipts, Errors, etc.
  • noexcept em cleanup e observadores: marca funções que nunca lançam.

2. Instalação

Aguardando primeira publicação. Quando disponível:

Via vcpkg (recomendado)

# Instalar vcpkg
git clone https://github.com/microsoft/vcpkg.git
./vcpkg/bootstrap-vcpkg.sh
./vcpkg/vcpkg integrate install

# Instalar paebiru
./vcpkg/vcpkg install paebiru

Via Conan 2 (cross-platform)

conan install paebiru/0.1.0@

Via CMake FetchContent (header-only)

# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(my_paebiru_app LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(paebiru 0.1 REQUIRED)
target_link_libraries(myapp PRIVATE paebiru::paebiru)
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/myapp

Verificação

// main.cpp
#include <paebiru/paebiru.hpp>
#include <cstdio>

int main() {
    std::printf("paebiru-cpp %d.%d\n",
                paebiru::version_major, paebiru::version_minor);
    return 0;
}
g++ -std=c++23 -o check_paebiru main.cpp -lpaebiru
./check_paebiru
# → paebiru-cpp 0

Dependências runtime

  • C++23 compiler (primário): GCC ≥ 13, Clang ≥ 17, MSVC ≥ 19.36
  • C++20 compiler (mínimo para coroutines + modules)
  • libc (sempre disponível)
  • libpthread (Linux, para std::jthread)
  • libpaebiru.so/.dylib/.dll (a base C, linkada automaticamente via find_package/Conan)
  • Opcional: vcpkg ou Conan (package management)

3. Exemplo de Uso

Header paebiru.hpp (a API C++ idiomática)

// include/paebiru/paebiru.hpp
#pragma once

// Inclui o header C dentro de extern "C"
extern "C" {
#include <paebiru.h>
}

#include <cstdint>
#include <cstddef>
#include <span>
#include <string_view>
#include <memory>
#include <optional>
#include <expected>  // C++23; C++20 use tl::expected
#include <variant>
#include <chrono>
#include <concepts>
#include <ranges>
#include <generator>  // C++23
#include <format>
#include <iostream>

namespace paebiru {

// =================================================================
// Constants
// =================================================================

inline constexpr std::size_t max_cid_bytes   = 32;
inline constexpr std::size_t max_cid_hex_len = 64;
inline constexpr std::size_t max_peer_id_len = 128;
inline constexpr std::uint16_t default_port  = 1975;
inline constexpr std::string_view default_port_str = "1975";

inline constexpr int version_major = PAEBIRU_VERSION_MAJOR;
inline constexpr int version_minor = PAEBIRU_VERSION_MINOR;
inline constexpr int version_patch = PAEBIRU_VERSION_PATCH;
inline constexpr std::string_view version_string = "0.1.0";

// =================================================================
// Error handling
// =================================================================

enum class error {
    ok                 = PAEBIRU_OK,
    invalid_argument   = PAEBIRU_ERR_INVALID_ARG,
    out_of_memory      = PAEBIRU_ERR_OUT_OF_MEMORY,
    network            = PAEBIRU_ERR_NETWORK,
    io                 = PAEBIRU_ERR_IO,
    timeout            = PAEBIRU_ERR_TIMEOUT,
    not_found          = PAEBIRU_ERR_NOT_FOUND,
    already            = PAEBIRU_ERR_ALREADY,
    internal           = PAEBIRU_ERR_INTERNAL,
};

[[nodiscard]]
constexpr error from_c(paebiru_error_t e) noexcept {
    return static_cast<error>(static_cast<int>(e));
}

[[nodiscard]]
inline std::string_view error_str(error e) noexcept {
    return paebiru_error_str(static_cast<paebiru_error_t>(static_cast<int>(e)));
}

template <typename T>
using result = std::expected<T, error>;

// =================================================================
// RAII Deleters
// =================================================================

namespace detail {

struct node_deleter {
    void operator()(paebiru_node_t* n) const noexcept {
        if (n) paebiru_node_destroy(n);
    }
};
struct identity_deleter {
    void operator()(paebiru_identity_t* i) const noexcept {
        if (i) paebiru_identity_destroy(i);
    }
};
struct receipt_deleter {
    void operator()(paebiru_receipt_t* r) const noexcept {
        if (r) paebiru_receipt_destroy(r);
    }
};

using node_handle     = std::unique_ptr<paebiru_node_t, node_deleter>;
using identity_handle = std::unique_ptr<paebiru_identity_t, identity_deleter>;
using receipt_handle  = std::unique_ptr<paebiru_receipt_t, receipt_deleter>;

}  // namespace detail

// =================================================================
// Receipt (POD, copyable, trivially destructible)
// =================================================================

class receipt {
public:
    std::array<std::uint8_t, max_cid_bytes> cid{};
    std::array<char, max_cid_hex_len + 1>   cid_hex{};
    std::uint64_t micro_joules  = 0;
    bool          is_healthy    = false;
    std::uint64_t timestamp_ns  = 0;

    [[nodiscard]] constexpr std::string_view cid_hex_view() const noexcept {
        return {cid_hex.data(), max_cid_hex_len};
    }
};

// =================================================================
// Mesh Event (variant of subtypes)
// =================================================================

class peer_connected_event {
public:
    std::string peer_id;
    std::chrono::system_clock::time_point timestamp;
};

class peer_lost_event {
public:
    std::string peer_id;
    std::string reason;
    std::chrono::system_clock::time_point timestamp;
};

class receipt_produced_event {
public:
    receipt receipt;
    std::chrono::system_clock::time_point timestamp;
};

using mesh_event = std::variant<
    peer_connected_event,
    peer_lost_event,
    receipt_produced_event
>;

// =================================================================
// Node (RAII wrapper)
// =================================================================

class node {
public:
    // --- Construction ---
    [[nodiscard]]
    static result<node> create(std::string_view storage_path) {
        // std::string_view → null-terminated C string
        std::string path{storage_path};  // implicit NUL terminator
        paebiru_node_t* raw = paebiru_node_create(path.c_str());
        if (!raw) {
            return std::unexpected{error::invalid_argument};
        }
        node n;
        n.handle_ = detail::node_handle{raw};
        return n;
    }

    // Rule of Zero: sem destrutor custom (unique_ptr cuida)
    // Sem copy constructor/assignment (unique_ptr é move-only)
    // Move permitido via default

    node(const node&) = delete;
    node& operator=(const node&) = delete;
    node(node&&) noexcept = default;
    node& operator=(node&&) noexcept = default;

    // --- Lifecycle ---

    [[nodiscard]]
    result<void> start() noexcept {
        auto err = paebiru_node_start(handle_.get());
        if (err != PAEBIRU_OK) {
            return std::unexpected{from_c(err)};
        }
        return {};
    }

    [[nodiscard]]
    result<void> stop() noexcept {
        auto err = paebiru_node_stop(handle_.get());
        if (err != PAEBIRU_OK) {
            return std::unexpected{from_c(err)};
        }
        return {};
    }

    // --- Messaging (zero-copy) ---

    [[nodiscard]]
    result<receipt> send_message(
        std::string_view target,
        std::span<const std::byte> payload
    ) noexcept {
        // std::string_view é não-owning; .data() não é garantido
        // NUL-terminated, então construímos string para o target.
        std::string target_str{target};
        receipt r;
        auto err = paebiru_node_send_message(
            handle_.get(),
            target_str.c_str(), target_str.size(),
            reinterpret_cast<const std::uint8_t*>(payload.data()),
            payload.size(),
            reinterpret_cast<paebiru_receipt_t*>(&r)
        );
        if (err != PAEBIRU_OK) {
            return std::unexpected{from_c(err)};
        }
        return r;
    }

    // --- Event stream (coroutine, C++20) ---

    [[nodiscard]]
    std::generator<mesh_event> events() {
        while (true) {
            paebiru_mesh_event_t raw;
            auto err = paebiru_node_poll_event(handle_.get(), &raw);
            if (err == PAEBIRU_OK) {
                co_yield convert_event(raw);
            } else if (err == PAEBIRU_ERR_TIMEOUT) {
                std::this_thread::sleep_for(std::chrono::milliseconds{10});
            } else {
                break;  // termina o generator
            }
        }
    }

    // --- Status ---

    [[nodiscard]]
    result<paebiru_node_status_t> status() const noexcept {
        paebiru_node_status_t s{};
        auto err = paebiru_node_get_status(handle_.get(), &s);
        if (err != PAEBIRU_OK) {
            return std::unexpected{from_c(err)};
        }
        return s;
    }

    // --- Accessors ---

    [[nodiscard]] paebiru_node_t* native_handle() const noexcept {
        return handle_.get();
    }

private:
    node() = default;  // para create()

    static mesh_event convert_event(const paebiru_mesh_event_t& raw) {
        switch (paebiru_event_get_type(&raw)) {
            case PAEBIRU_EVENT_PEER_CONNECTED: {
                std::string peer(paebiru_event_get_peer_id(&raw),
                                 paebiru_event_get_peer_id_len(&raw));
                return peer_connected_event{std::move(peer), std::chrono::system_clock::now()};
            }
            case PAEBIRU_EVENT_PEER_LOST: {
                std::string peer(paebiru_event_get_peer_id(&raw),
                                 paebiru_event_get_peer_id_len(&raw));
                std::string reason(reinterpret_cast<const char*>(
                                       paebiru_event_get_payload(&raw)),
                                   paebiru_event_get_payload_len(&raw));
                return peer_lost_event{std::move(peer), std::move(reason),
                                        std::chrono::system_clock::now()};
            }
            case PAEBIRU_EVENT_RECEIPT_PRODUCED: {
                const auto* raw_receipt = paebiru_event_get_receipt(&raw);
                receipt r;
                std::memcpy(r.cid.data(), paebiru_receipt_get_cid(raw_receipt),
                            max_cid_bytes);
                std::memcpy(r.cid_hex.data(),
                            paebiru_receipt_get_cid_hex(raw_receipt),
                            max_cid_hex_len);
                r.cid_hex[max_cid_hex_len] = '\0';
                r.micro_joules = paebiru_receipt_get_micro_joules(raw_receipt);
                r.is_healthy = paebiru_receipt_is_algedonically_healthy(raw_receipt);
                r.timestamp_ns = paebiru_receipt_get_timestamp_ns(raw_receipt);
                return receipt_produced_event{std::move(r),
                                              std::chrono::system_clock::now()};
            }
            default:
                std::unreachable();
        }
    }

    detail::node_handle handle_;
};

}  // namespace paebiru

Programa principal (estilo C++23 idiomático)

// examples/hello_paebiru.cpp
#include <paebiru/paebiru.hpp>
#include <print>
#include <vector>
#include <string>
#include <cstring>

int main() {
    using namespace paebiru;

    // 1. Criar nó (result<node, error>)
    auto result = node::create("./data");
    if (!result) {
        std::println(stderr, "Failed to create node: {}",
                      error_str(result.error()));
        return 1;
    }
    auto n = std::move(*result);

    // 2. Iniciar nó
    if (auto err = n.start(); !err) {
        std::println(stderr, "Failed to start: {}", error_str(err.error()));
        return 1;
    }

    // 3. Subscrever a eventos via coroutine + ranges (C++20)
    //    (em uma thread separada)
    std::jthread event_loop([&n](std::stop_token st) {
        for (const auto& event : n.events()) {
            std::visit([](const auto& e) {
                using T = std::decay_t<decltype(e)>;
                if constexpr (std::is_same_v<T, peer_connected_event>) {
                    std::println("[peer up]   {}", e.peer_id);
                } else if constexpr (std::is_same_v<T, peer_lost_event>) {
                    std::println("[peer down] {} ({})", e.peer_id, e.reason);
                } else if constexpr (std::is_same_v<T, receipt_produced_event>) {
                    std::println("[receipt]   cid={} µJ={} ok={}",
                                 e.receipt.cid_hex_view(),
                                 e.receipt.micro_joules,
                                 e.receipt.is_healthy);
                }
            }, event);

            if (st.stop_requested()) break;
        }
    });

    // 4. Enviar mensagem (zero-copy via std::span)
    const char payload_text[] = "hello from C++23";
    std::span<const std::byte> payload{
        reinterpret_cast<const std::byte*>(payload_text),
        sizeof(payload_text) - 1  // exclui NUL
    };

    auto send_result = n.send_message("audit_mesh", payload);
    if (send_result) {
        std::println("Receipt CID: {}", send_result->cid_hex_view());
        std::println("Custo µJ:     {}", send_result->micro_joules);
        std::println("Algedonic OK: {}", send_result->is_healthy);
    } else {
        std::println(stderr, "Send failed: {}",
                      error_str(send_result.error()));
    }

    // 5. Aguarda Ctrl+C para shutdown graceful
    std::cin.get();
    event_loop.request_stop();
    event_loop.join();

    // 6. Stop explícito (cleanup via RAII no destrutor seria
    //    igualmente seguro; stop() é graceful).
    n.stop();
    return 0;
}

4. Integração com Unreal, OpenCV, ROS2 e Trading

Unreal Engine 5 — Plugin C++

UE5 usa C++20 + Modules. Plugin example:

// Source/PaebiruMesh/Private/PaebiruMesh.cpp
#include "PaebiruMesh.h"
#include "Async/Async.h"  // TWeakObjectPtr

void FPaebiruMeshSubsystem::Initialize(FSubsystemCollectionBase& Collection) {
    Super::Initialize(Collection);

    auto Result = paebiru::node::create(FPaths::ProjectPersistentDownloadDir() / TEXT("paebiru"));
    if (!Result) {
        UE_LOG(LogTemp, Error, TEXT("Paebiru node creation failed: %.*s"),
               paebiru::error_str(Result.error()).data());
        return;
    }
    Node = std::move(*Result);
    Node->start();

    // Subscribe em game thread
    EventThread = FRunnableThread::Create(this, TEXT("PaebiruEventThread"));
}

void FPaebiruMeshSubsystem::Tick(float DeltaTime) {
    TOptional<paebiru::receipt> LastReceipt;
    if (CurrentReceiptQueue.Dequeue(LastReceipt)) {
        OnReceipt.Broadcast(LastReceipt.GetValue());
    }
}

OpenCV + computer vision pipeline

#include <paebiru/paebiru.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/dnn.hpp>

void processCameraFeed(const std::string& camera_url,
                       paebiru::node& n) {
    cv::VideoCapture cap(camera_url);
    cv::Mat frame;
    cv::dnn::Net yolo = cv::dnn::readNet("yolov8n.onnx");

    while (cap.read(frame)) {
        // Detecção YOLO
        cv::Mat blob;
        cv::dnn::blobFromImage(frame, blob);
        yolo.setInput(blob);
        std::vector<cv::Mat> outputs;
        yolo.forward(outputs);

        // Envia detecção como CausalBlock
        std::vector<std::byte> payload(
            outputs[0].ptr<std::byte>(),
            outputs[0].ptr<std::byte>() + outputs[0].total() * outputs[0].elemSize()
        );
        auto result = n.send_message("perception_audit",
            std::span<const std::byte>{payload.data(), payload.size()});
        if (!result) {
            std::println(stderr, "Send failed: {}",
                          paebiru::error_str(result.error()));
        }
    }
}

ROS2 (Robot Operating System 2) — C++ canônico

ROS2 Humble/Iron usa C++17. Integre PAEBIRU como nó ROS2:

// paebiru_ros2_node.cpp
#include <rclcpp/rclcpp.hpp>
#include <paebiru/paebiru.hpp>

class PaebiruNode : public rclcpp::Node {
public:
    PaebiruNode() : Node("paebiru_ros2_node") {
        auto result = paebiru::node::create("/var/lib/paebiru");
        if (!result) {
            RCLCPP_ERROR(get_logger(), "Failed to create PAEBIRU node");
            throw std::runtime_error("paebiru init failed");
        }
        mesh_node_ = std::make_unique<paebiru::node>(std::move(*result));
        mesh_node_->start();

        // Subscriber ROS2 → publisher PAEBIRU
        cmd_sub_ = create_subscription<std_msgs::msg::String>(
            "cmd", 10,
            [this](const std_msgs::msg::String& msg) {
                std::span<const std::byte> payload{
                    reinterpret_cast<const std::byte*>(msg.data.data()),
                    msg.data.size()
                };
                auto result = mesh_node_->send_message("cmd_audit", payload);
                if (!result) {
                    RCLCPP_WARN(get_logger(), "PAEBIRU send failed: %.*s",
                                paebiru::error_str(result.error()).data());
                }
            });
    }

private:
    std::unique_ptr<paebiru::node> mesh_node_;
    rclcpp::Subscription<std_msgs::msg::String>::SharedPtr cmd_sub_;
};

int main(int argc, char** argv) {
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<PaebiruNode>());
    rclcpp::shutdown();
    return 0;
}

High-Frequency Trading (HFT) — latência sub-microsegundo

#include <paebiru/paebiru.hpp>
#include <chrono>
#include <print>

void hft_loop(paebiru::node& n) {
    // Pre-allocate buffer uma vez (zero reallocation)
    std::array<std::byte, 1024> order_buffer;

    // Tight loop: medir latência end-to-end
    for (int i = 0; i < 1'000'000; ++i) {
        // Preenche order (omitted)
        std::size_t order_size = fill_order(order_buffer.data(), order_buffer.size());

        const auto t0 = std::chrono::high_resolution_clock::now();
        auto result = n.send_message(
            "exchange_mesh",
            std::span<const std::byte>{order_buffer.data(), order_size}
        );
        const auto t1 = std::chrono::high_resolution_clock::now();

        if (!result) {
            std::println(stderr, "Send failed: {}",
                          paebiru::error_str(result.error()));
        }

        const auto latency_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0).count();
        if (latency_ns > 1000) {
            std::println(stderr, "ALGEDONIC: latency {} ns", latency_ns);
        }
    }
}

Qt6 GUI (event loop integration)

#include <QCoreApplication>
#include <QObject>
#include <paebiru/paebiru.hpp>

class PaebiruBridge : public QObject {
    Q_OBJECT
public:
    explicit PaebiruBridge(paebiru::node& n, QObject* parent = nullptr)
        : QObject(parent), node_(n) {
        // Polling thread usando std::jthread
        worker_ = std::jthread([this](std::stop_token st) {
            for (const auto& event : node_.events()) {
                emit eventReceived();
                if (st.stop_requested()) break;
            }
        });
    }

    ~PaebiruBridge() override {
        worker_.request_stop();
        worker_.join();
    }

signals:
    void eventReceived();

private:
    paebiru::node& node_;
    std::jthread worker_;
};

#include "main.moc"

CMakeLists.txt para projeto C++23

cmake_minimum_required(VERSION 3.20)
project(my_paebiru_cpp_app LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)  # C++23 strict, no GNU/MSVC extensions

find_package(paebiru 0.1 REQUIRED)

add_executable(hello_paebiru examples/hello_paebiru.cpp)
target_link_libraries(hello_paebiru PRIVATE paebiru::paebiru)

# HFT example: optimization
add_executable(hft_loop examples/hft_loop.cpp)
target_link_libraries(hft_loop PRIVATE paebiru::paebiru)
target_compile_options(hft_loop PRIVATE
    -O3 -march=native -flto -fno-plt
    -Wpedantic -Werror
)

# Tests com Catch2 v3
include(FetchContent)
FetchContent_Declare(Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git
                               GIT_TAG v3.5.0)
FetchContent_MakeAvailable(Catch2)

add_executable(test_paebiru tests/test_paebiru.cpp)
target_link_libraries(test_paebiru PRIVATE paebiru::paebiru Catch2::Catch2WithMain)

include(Catch)
catch_discover_tests(test_paebiru)

# Module C++20 (se alvo for C++20+)
if(CMAKE_CXX_STANDARD GREATER_EQUAL 20)
    target_sources(hello_paebiru PUBLIC FILE_SET paebiru_module TYPE CXX_MODULES)
endif()

Module C++20 (paebiru.cppm)

// include/paebiru/paebiru.cppm
export module paebiru;

export {
    // Constants
    inline constexpr std::size_t max_cid_bytes = 32;
    // ... outras constantes ...
}

export import <span>;
export import <string_view>;
export import <memory>;
export import <expected>;
// ... outros imports ...

export namespace paebiru {
    enum class error { /* ... */ };
    class receipt { /* ... */ };
    class node { /* ... */ };
    // ... outras classes ...
}

5. Veja também

🐍 Python (paebiru-py)

O binding Python é, entre os 24+ do projeto, o canônico para ciência de dados, ML/AI federado, scripting científico, e automação. Python é a lingua franca de ML (PyTorch, JAX, TensorFlow, scikit-learn, Hugging Face) e casa com PAEBIRU via FedAvg nativo sobre paebiru-learn e via integração NumPy/PyTorch zero-copy para deltas de gradient. Mais: o ecossistema Python (numpy, pandas, polars, matplotlib, jupyter, pytest, mypy) torna Python a linguagem mais produtiva para prototipagem e experimentação de mesh.

O binding usa PyO3 (a crate Rust que gera bindings Python para Rust) para expor paebiru-c (via paebiru-rust) como módulo Python nativo, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com __init__.py strict, dataclass(frozen=True) para Receipt e MeshEvent, context managers (with) para cleanup determinístico, async/await para hot-path, e numpy.frombuffer / torch.frombuffer para zero-copy de buffers nativos.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via __init__ PyO3 + __del__ cleanup: instâncias nativas (nó, identidade, recibo) são representadas como classes Python (Node, Receipt, MeshEvent) que encapsulam um c_void_p (ponteiro opaco vindo de Rust via PyO3). __del__ chama paebiru_node_destroy quando o objeto é coletado pelo GC do Python. Context managers (with Node() as node:) fornecem cleanup determinístico imediato.
  • Convenção de nomenclatura:
    • Classes em PascalCase (Node, Receipt, MeshEvent).
    • Funções, métodos, variáveis em snake_case (send_message, storage_path, is_healthy).
    • Constantes em UPPER_SNAKE_CASE (DEFAULT_PORT, MAX_PLASMID_SIZE).
    • Módulos em snake_case (paebiru.mesh, paebiru.receipt).
    • Type hints obrigatórios em todo o código público (Python 3.10+ union syntax X | Y, lowercase builtins).
    • Dataclasses frozen para tipos imutáveis: @dataclass(frozen=True, slots=True) para Receipt.
  • Gerenciamento de memória: classes encapsulando handles C implementam __enter__/__exit__ (context manager) para cleanup determinístico. __del__ registra cleanup automático via GC como safety net. weakref.finalize oferece cleanup mesmo com referência circular.
  • Distribuição: pacote PyPI paebiru (instalação via pip install paebiru). Wheels manylinux/musllinux/macOS/ Windows via cibuildwheel. Para NumPy/PyTorch integration, extras_require: paebiru[numpy], paebiru[torch], paebiru[jax].
  • Type safety: from __future__ import annotations + mypy --strict garante que a API é type-safe. Protocol classes (MeshEventHandler) para structural typing.
  • Async/await: asyncio nativo para hot-path; AsyncIterator[MeshEvent] para stream de eventos via async for. Casa com aiohttp, httpx, asyncio.gather.
  • Zero-cópia via NumPy/PyTorch: numpy.frombuffer para interpretar memória C como numpy.ndarray; torch.frombuffer para torch.Tensor. Ambas evitam cópia via np.ndarray.base apontando para ctypes raw.
  • PEP 544 Protocols para interfaces duck-typed:
    class MeshEventHandler(Protocol):
        def __call__(self, event: MeshEvent) -> None: ...
    
  • match statement (Python 3.10+) para discriminação de MeshEvent.type:
    match event:
        case PeerConnected(peer_id): ...
        case PeerLost(peer_id, reason): ...
        case ReceiptProduced(receipt): ...
    
  • __repr__ explícito para debug: repr(node) mostra Node(storage_path='~/.paebiru', handle=0x...).

2. Instalação

pip install paebiru

Extras opcionais

pip install paebiru[numpy]    # + NumPy zero-copy
pip install paebiru[torch]    # + PyTorch zero-copy
pip install paebiru[jax]      # + JAX zero-copy
pip install paebiru[async]    # + asyncio support
pip install paebiru[dev]      # + pytest, mypy, ruff, black
pip install paebiru[all]      # tudo

Verificação

import paebiru
print(paebiru.__version__)

Dependências runtime

  • Python ≥ 3.10 (para match, union syntax X | Y, dataclass(slots=True))
  • pip ≥ 21 com suporte a wheels manylinux
  • libc (sempre disponível)
  • Opcional: NumPy ≥ 1.21, PyTorch ≥ 1.10, JAX ≥ 0.4
  • Opcional para desenvolvimento: mypy ≥ 1.0, pytest ≥ 7, ruff (linter), black (formatter)

3. Exemplo de Uso

Definições PyO3 (lado Rust)

#![allow(unused)]
fn main() {
// paebiru-core/src/python.rs
use pyo3::prelude::*;
use pyo3::types::PyBytes;
use paebiru_c as core;

/// Binding Python via PyO3
#[pymodule]
fn paebiru(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add("__version__", env!("CARGO_PKG_VERSION"))?;
    m.add_class::<PyNode>()?;
    m.add_class::<PyReceipt>()?;
    m.add_class::<PyMeshEvent>()?;
    m.add_function(wrap_pyfunction!(py_send_message, m)?)?;
    Ok(())
}

#[pyclass(name = "Node")]
#[derive(Clone)]
pub struct PyNode {
    inner: core::Node,
}

#[pymethods]
impl PyNode {
    #[new]
    fn new(storage_path: &str) -> PyResult<Self> {
        let node = core::Node::create(storage_path)
            .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
        Ok(PyNode { inner: node })
    }

    fn start(&self) -> PyResult<()> {
        self.inner.start()
            .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e.to_string()))
    }

    fn send_message<'py>(
        &self,
        py: Python<'py>,
        target_id: &str,
        payload: &'py PyBytes,
    ) -> PyResult<PyReceipt> {
        let receipt = self.inner
            .send_message(target_id, payload.as_bytes())
            .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e.to_string()))?;
        Ok(PyReceipt { inner: receipt })
    }

    fn __enter__(slf: PyRef<Self>) -> PyRef<Self> { slf }
    fn __exit__(slf: PyRef<Self>, _exc_type: &PyAny, _exc_val: &PyAny, _exc_tb: &PyAny) -> PyResult<bool> {
        // Cleanup automático (sempre, mesmo em exceção)
        Ok(false)  // não suprime exceção
    }

    fn __repr__(&self) -> String {
        format!("Node(storage_path={:?})", self.inner.storage_path())
    }

    fn __del__(&mut self) {
        // Safety net: cleanup se __exit__ não foi chamado
        let _ = self.inner.destroy();
    }
}
}

Tipos Python (dataclasses frozen + slots)

# paebiru/types.py
from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum, auto
from typing import NewType, final
import numpy as np
from numpy.typing import NDArray

PeerId = NewType("PeerId", str)


class EventType(Enum):
    """Tipo discriminado de MeshEvent."""
    PEER_CONNECTED = auto()
    PEER_LOST = auto()
    RECEIPT_PRODUCED = auto()


@final
@dataclass(frozen=True, slots=True)
class Receipt:
    """Recibo Soberano (imutável, hashable)."""
    cid: bytes                   # 32 bytes raw
    cid_hex: str                 # 64 chars hex
    micro_joules: int
    is_healthy: bool

    def __post_init__(self) -> None:
        if len(self.cid) != 32:
            raise ValueError(f"cid must be 32 bytes, got {len(self.cid)}")
        if len(self.cid_hex) != 64:
            raise ValueError(f"cid_hex must be 64 chars, got {len(self.cid_hex)}")
        if self.micro_joules < 0:
            raise ValueError(f"micro_joules must be non-negative")

    def __repr__(self) -> str:
        return (
            f"Receipt(cid_hex='{self.cid_hex[:16]}...', "
            f"µJ={self.micro_joules}, healthy={self.is_healthy})"
        )


@final
@dataclass(frozen=True, slots=True)
class MeshEvent:
    """Evento da malha (imutável)."""
    type: EventType
    peer_id: PeerId
    timestamp_ns: int  # nanoseconds since epoch
    receipt: Receipt | None = None  # populado se type == RECEIPT_PRODUCED

    def __post_init__(self) -> None:
        if self.type == EventType.RECEIPT_PRODUCED and self.receipt is None:
            raise ValueError("RECEIPT_PRODUCED event must have receipt")
        if self.type != EventType.RECEIPT_PRODUCED and self.receipt is not None:
            raise ValueError("Only RECEIPT_PRODUCED event should have receipt")

    def __repr__(self) -> str:
        return f"MeshEvent({self.type.name}, peer_id={self.peer_id!r})"

Classe Node com context manager, async, e numpy

# paebiru/node.py
from __future__ import annotations

import asyncio
import contextlib
import logging
import time
from collections.abc import AsyncIterator, Callable
from typing import Protocol, final

import numpy as np
from numpy.typing import NDArray

from paebiru._native import (
    Node as _NativeNode,
    send_message as _native_send_message,
    PAEBIRU_DEFAULT_PORT,
)
from paebiru.types import MeshEvent, Receipt, EventType, PeerId

logger = logging.getLogger(__name__)


class MeshEventHandler(Protocol):
    """Protocol duck-typed para callbacks de eventos."""
    def __call__(self, event: MeshEvent) -> None: ...


@final
class Node:
    """Cliente do nó PAEBIRU.

    Exemplo:
        with Node(storage_path="~/.paebiru") as node:
            node.start()
            receipt = node.send_message("audit_mesh", b"hello")
            print(receipt)
    """

    def __init__(
        self,
        storage_path: str,
        *,
        listen_port: int = PAEBIRU_DEFAULT_PORT,
    ) -> None:
        self._storage_path = storage_path
        self._listen_port = listen_port
        self._native = _NativeNode(storage_path)
        self._started = False
        self._closed = False
        self._event_handlers: list[MeshEventHandler] = []

    def start(self) -> None:
        """Inicia o nó (síncrono, bloqueia até estar pronto)."""
        if self._started:
            return
        self._native.start()
        self._started = True
        logger.info("PAEBIRU node started at %s", self._storage_path)

    def stop(self) -> None:
        """Para o nó gracefully."""
        if not self._started or self._closed:
            return
        self._native.stop()
        self._started = False
        logger.info("PAEBIRU node stopped")

    def send_message(
        self,
        target: str,
        payload: bytes | NDArray[np.uint8] | memoryview,
    ) -> Receipt:
        """Envia mensagem síncrona e retorna Recibo Soberano."""
        if not self._started:
            raise RuntimeError("Node not started; call .start() first")
        # Zero-copy para numpy/memoryview: usa memoryview.tobytes()
        # apenas se necessário; caso contrário, passa direto.
        if isinstance(payload, np.ndarray):
            payload = memoryview(payload).cast("B")  # zero-copy
        elif isinstance(payload, memoryview):
            payload = payload.cast("B")
        return _native_send_message(
            self._native,
            target,
            bytes(payload),  # segura cópia
        )

    def send_message_async(
        self,
        target: str,
        payload: bytes,
    ) -> asyncio.Future[Receipt]:
        """Envia mensagem assíncrona via asyncio.Future."""
        return asyncio.get_event_loop().run_in_executor(
            None, self.send_message, target, payload
        )

    async def events(self) -> AsyncIterator[MeshEvent]:
        """Async iterator de eventos da malha."""
        loop = asyncio.get_event_loop()
        while not self._closed:
            event = await loop.run_in_executor(None, self._native.poll_event)
            if event is not None:
                yield event

    def subscribe(self, handler: MeshEventHandler) -> Callable[[], None]:
        """Subscreve um handler para eventos. Retorna callable de unsub."""
        self._event_handlers.append(handler)
        return lambda: self._event_handlers.remove(handler)

    # --- context manager ---

    def __enter__(self) -> Node:
        return self

    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        self.stop()

    def __del__(self) -> None:
        try:
            self.stop()
        except Exception:  # noqa: BLE001
            pass  # GC safety net

    def __repr__(self) -> str:
        return (
            f"Node(storage_path={self._storage_path!r}, "
            f"started={self._started}, closed={self._closed})"
        )

Programa principal (estilo Python idiomático)

# examples/hello_paebiru.py
from __future__ import annotations

import asyncio
import logging

from paebiru import Node, MeshEvent, EventType

logging.basicConfig(level=logging.INFO)


def on_mesh_event(event: MeshEvent) -> None:
    """Handler para eventos de malha."""
    match event:
        case MeshEvent(type=EventType.PEER_CONNECTED, peer_id=peer_id):
            print(f"[peer up]   {peer_id}")
        case MeshEvent(type=EventType.PEER_LOST, peer_id=peer_id):
            print(f"[peer down] {peer_id}")
        case MeshEvent(type=EventType.RECEIPT_PRODUCED, receipt=receipt):
            print(f"[receipt]   {receipt}")


def main_sync() -> None:
    """Versão síncrona com context manager."""
    with Node(storage_path="~/.paebiru") as node:
        node.start()

        # Subscreve handler
        unsubscribe = node.subscribe(on_mesh_event)

        # Envia mensagem
        receipt = node.send_message("audit_mesh", b"hello from python")
        print(f"Receipt CID: {receipt.cid_hex}")
        print(f"Custo µJ:     {receipt.micro_joules}")
        print(f"Algedonic OK: {receipt.is_healthy}")

        unsubscribe()  # cleanup explícito do handler


async def main_async() -> None:
    """Versão async com async iterator."""
    with Node(storage_path="~/.paebiru") as node:
        node.start()

        # Async send
        receipt_future = node.send_message_async("audit_mesh", b"hello")
        receipt = await receipt_future
        print(f"Async receipt: {receipt.cid_hex}")

        # Async event stream
        async for event in node.events():
            print(f"Async event: {event}")


if __name__ == "__main__":
    main_sync()
    asyncio.run(main_async())

4. Integração com NumPy, PyTorch, pytest e cibuildwheel

NumPy zero-copy para FedAvg

# examples/fedavg_numpy.py
from __future__ import annotations

import numpy as np
from numpy.typing import NDArray

from paebiru import Node

def compute_local_delta(
    global_weights: NDArray[np.float32],
    local_data: NDArray[np.float32],
) -> NDArray[np.float32]:
    """Computa weight delta local (placeholder)."""
    # ... lógica real de FedAvg aqui ...
    return local_data - global_weights  # simplificado

def main() -> None:
    # Carrega pesos globais do BC de Aprendizado
    global_weights: NDArray[np.float32] = np.load("global.npy")
    local_data: NDArray[np.float32] = np.load("local.npy")

    # Computa delta como array NumPy
    delta = compute_local_delta(global_weights, local_data)

    with Node(storage_path="~/.paebiru") as node:
        node.start()
        # Zero-copy: NumPy → memoryview → C
        delta_bytes = memoryview(delta).cast("B")
        receipt = node.send_message(
            "coordinator_peer",
            delta_bytes,  # zero-copy até a fronteira FFI
        )
        print(f"Delta sent: {delta.nbytes} bytes, receipt {receipt.cid_hex}")

PyTorch zero-copy

# examples/fedavg_torch.py
from __future__ import annotations

import torch
from paebiru import Node

def main() -> None:
    # Modelo local (PyTorch)
    local_weights = {k: torch.randn(1000, 1000) for k in ["w1", "w2", "w3"]}

    # Serializa dict de tensors para buffer contíguo (zero-copy via numpy)
    delta_bytes = b"".join(
        t.detach().numpy().tobytes() for t in local_weights.values()
    )

    with Node(storage_path="~/.paebiru") as node:
        node.start()
        receipt = node.send_message("coordinator", delta_bytes)
        print(f"Sent {len(delta_bytes)} bytes (PyTorch zero-copy)")

    # Versão ainda mais zero-copy (sem numpy intermediário):
    # use `t.untyped_storage()` (PyTorch ≥ 2.1) para acessar o
    # buffer raw e criar memoryview diretamente.

pytest (property-based testing)

# tests/test_paebiru.py
from __future__ import annotations

import pytest
from hypothesis import given, strategies as st

from paebiru import Node, MeshEvent, EventType, Receipt


def test_send_message_returns_valid_receipt(tmp_path) -> None:
    """Envia mensagem e valida estrutura do Recibo."""
    storage = tmp_path / "paebiru"
    with Node(storage_path=str(storage)) as node:
        node.start()
        receipt = node.send_message("audit_mesh", b"hello")
        assert isinstance(receipt, Receipt)
        assert len(receipt.cid) == 32
        assert len(receipt.cid_hex) == 64
        assert receipt.micro_joules >= 0
        assert isinstance(receipt.is_healthy, bool)


def test_context_manager_cleanup(tmp_path) -> None:
    """Context manager deve cleanup o handle mesmo em exceção."""
    storage = tmp_path / "paebiru"
    with pytest.raises(RuntimeError):
        with Node(storage_path=str(storage)) as node:
            node.start()
            raise RuntimeError("simulated")
    # Sem leak: handle C foi destruído via __exit__


@given(target=st.text(min_size=1, max_size=60), payload=st.binary(min_size=0, max_size=1024))
def test_send_message_property(target: str, payload: bytes) -> None:
    """Property: qualquer (target, payload) válido produz recibo."""
    with Node(storage_path="/tmp/paebiru-hypothesis") as node:
        node.start()
        receipt = node.send_message(target, payload)
        assert receipt is not None
        assert len(receipt.cid) == 32

pyproject.toml (PEP 621 + maturin para PyO3)

[build-system]
requires = ["maturin>=1.5"]
build-backend = "maturin"

[project]
name = "paebiru"
version = "0.1.0"
description = "Python binding for the PAEBIRU decentralized mesh"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "AGPL-3.0-or-later"}
authors = [{name = "PAEBIRU Team", email = "team@paebiru.org"}]
keywords = ["paebiru", "p2p", "mesh", "federated-learning", "sovereign-receipts"]
classifiers = [
    "Development Status :: 3 - Alpha",
    "Intended Audience :: Developers",
    "Intended Audience :: Science/Research",
    "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Topic :: System :: Distributed Computing",
    "Topic :: Scientific/Engineering :: Information Analysis",
]
dependencies = []

[project.optional-dependencies]
numpy = ["numpy>=1.21"]
torch = ["torch>=1.10"]
jax = ["jax>=0.4", "jaxlib>=0.4"]
async = []  # já é stdlib
dev = [
    "pytest>=7",
    "pytest-asyncio>=0.21",
    "hypothesis>=6",
    "mypy>=1.0",
    "ruff>=0.1",
    "black>=23",
    "maturin>=1.5",
]
all = ["paebiru[numpy,torch,jax,dev]"]

[project.urls]
Homepage = "https://paebiru.org"
Documentation = "https://paebiru.org/python"
Repository = "https://github.com/paebiru/paebiru-py"
Issues = "https://github.com/paebiru/paebiru-py/issues"

[tool.maturin]
# Configuração para build com maturin (PyO3 + Rust)
binding = "PyO3"
features = ["pyo3/extension-module"]
module-name = "paebiru._native"

[tool.mypy]
python_version = "3.10"
strict = true
warn_unreachable = true
disallow_untyped_decorators = true

[tool.ruff]
line-length = 100
target-version = "py310"

[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP", "B", "A", "C4", "DTZ", "TID", "ICN"]

cibuildwheel (cross-platform wheels)

# pyproject.toml [tool.cibuildwheel]
[tool.cibuildwheel]
build = ["cp310-*", "cp311-*", "cp312-*"]
skip = ["*-musllinux*", "*-win32"]
archs = ["x86_64", "aarch64"]
test-requires = ["pytest>=7", "hypothesis>=6"]
test-command = "pytest {project}/tests -v"

[tool.cibuildwheel.linux]
before-build = "dnf install -y libpaebiru-devel"
environment = {PAEBIRU_LIB_DIR = "/usr/local/lib"}

[tool.cibuildwheel.macos]
environment = {MACOSX_DEPLOYMENT_TARGET = "11.0"}

[tool.cibuildwheel.windows]
before-build = "pip install delvewheel"
repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel} --add-path C:\\libpaebiru"

5. Veja também

🕸️ TypeScript/WASM (paebiru-ts)

Permite rodar instâncias do PAEBIRU diretamente no navegador (dashboards de observabilidade, carteiras web, ferramentas de gossip), em Node.js (servidores, CLIs, jobs), e em runtimes alternativos como Deno, Bun e Cloudflare Workers (WASM Workers). O paebiru-c é compilado para wasm32-unknown-unknown via wasm-bindgen e exposto com tipos TypeScript gerados automaticamente, seguindo o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com ArrayBuffer / SharedArrayBuffer para zero-copy via WASM linear memory.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via number: instâncias nativas (nó, identidade, recibo) são representadas por um number (índice em uma tabela de handles do lado WASM) ou um BigInt (offset na WASM linear memory). O tipo PaebiruNode é uma classe TypeScript fina que mantém o handle em um campo private readonly #handle: number e o passa para funções WASM tipadas.
  • Convenção de nomenclatura:
    • Classes e tipos em PascalCase (PaebiruNode, Receipt, MeshEvent).
    • Métodos e propriedades em camelCase (start(), sendMessage(), microJoules).
    • Constantes em UPPER_SNAKE_CASE (DEFAULT_PORT, MAX_PLASMID_SIZE).
    • Discriminated unions para variantes de eventos (type: 'peer-connected' | 'peer-lost' | 'receipt').
  • Gerenciamento de memória: o PaebiruNode expõe async close(): Promise<void> (chama paebiru_node_destroy via WASM). Para cleanup automático com using (TS 5.2+): using node = await Node.init(...); — o Symbol.dispose é implementado.
  • Distribuição: pacote npm @paebiru/sdk (escopo @paebiru/ reservado). Builds triplos:
    • dist/index.mjs + dist/index.cjs (ESM + CommonJS)
    • dist/browser/paebiru.wasm (binary WASM, carregado via fetch + instantiateStreaming)
    • dist/types/ (declarações .d.ts geradas)
  • TypeScript strict: API é totalmente tipada; sem any em hot-path; noUncheckedIndexedAccess: true no tsconfig.json recomendado.
  • Async-first: toda API pública retorna Promise<T> ou é um AsyncIterable<T>. Casas com a metáfora de eventos do Kernel GALS.
  • Zero-cópia via ArrayBuffer:
    • Payloads entram/saem como Uint8Array (vista sobre ArrayBuffer).
    • Quando disponível, SharedArrayBuffer permite ao host e ao WASM compartilharem memória sem cópia (necessita COOP/COEP headers no servidor).
  • WebCrypto nativo: a stack criptográfica usa crypto.subtle (WebCrypto API) no navegador — mesmo primitivos do BLAKE3, Ed25519, ML-DSA, mas aproveitando aceleração de hardware.

2. Instalação

npm install @paebiru/sdk
# ou com pnpm
pnpm add @paebiru/sdk
# ou com yarn
yarn add @paebiru/sdk

Para Deno:

import { Node } from 'npm:@paebiru/sdk';

Para Bun:

bun add @paebiru/sdk

Para Cloudflare Workers (WASM), use o pacote específico:

npm install @paebiru/sdk-workers

3. Uso no Navegador

import { Node } from '@paebiru/sdk';

const node = await Node.init({
    storage: 'indexeddb',  // ou 'opfs' (Origin Private File System)
    wasmUrl: '/paebiru.wasm',  // opcional; detecta automaticamente
});

node.on('pulse', (peer) => {
    console.log(`Pulso recebido de ${peer.id}`);
});

await node.start();

Versão TypeScript idiomática (tipos explícitos, async/await)

import {
    Node,
    Receipt,
    MeshEvent,
    PeerId,
    MeshAddress,
} from '@paebiru/sdk';

// using (TS 5.2+) — cleanup automático mesmo se 'start' lançar
{
    using node = await Node.init({ storage: 'indexeddb' });
    await node.start();

    // Subscribe a eventos com tipos
    node.on('mesh-event', (event: MeshEvent) => {
        switch (event.type) {
            case 'peer-connected':
                console.log(`peer up: ${event.peerId}`);
                break;
            case 'peer-lost':
                console.log(`peer down: ${event.peerId} (${event.reason})`);
                break;
            case 'receipt-produced':
                console.log(`receipt: ${event.receipt.cid}`);
                break;
        }
    });

    // Envia mensagem e recebe Recibo Soberano
    const target: MeshAddress = MeshAddress.parse('12D3KooW...');
    const payload: Uint8Array = new TextEncoder().encode('hello');
    const receipt: Receipt = await node.sendMessage({ target, payload });

    console.log(`Receipt CID : ${receipt.cid}`);
    console.log(`Custo µJ     : ${receipt.microJoules}`);
    console.log(`Algedonic OK : ${receipt.isAlgedonicallyHealthy}`);
}
// 'using' chama node.close() automaticamente aqui

4. Uso em Node.js, Deno e Cloudflare Workers

Node.js (≥ 20, com --experimental-wasm-modules ou 22+ nativo)

import { Node } from '@paebiru/sdk';

const node = await Node.init({
    storage: 'fs:./.paebiru',  // filesystem local
    wasmUrl: new URL('./node_modules/@paebiru/sdk/dist/paebiru.wasm',
                      import.meta.url),
});
await node.start();

// ... mesma API do navegador ...
await node.close();

Deno (>= 2.0)

import { Node } from 'npm:@paebiru/sdk';

const node = await Node.init({
    storage: `fs:${Deno.cwd()}/.paebiru`,
});
await node.start();

Bun (≥ 1.0)

import { Node } from '@paebiru/sdk';

const node = await Node.init({ storage: 'fs:./.paebiru' });
await node.start();

Cloudflare Workers (WASM, sem Node API)

// src/index.ts (Worker entrypoint)
import { Node } from '@paebiru/sdk-workers';

export interface Env {
    PAEBIRU_STORAGE: R2Bucket;  // R2 binding para storage durável
}

export default {
    async fetch(request: Request, env: Env): Promise<Response> {
        const node = await Node.init({
            storage: 'r2:' + env.PAEBIRU_STORAGE.name,
        });
        await node.start();

        // Processa requisição via node e retorna Recibo Soberano
        const receipt = await node.handleHttpRequest(request);

        return new Response(JSON.stringify(receipt, null, 2), {
            headers: { 'content-type': 'application/json' },
        });
    },
};

Configure wrangler.toml:

name = "paebiru-worker"
main = "src/index.ts"
compatibility_date = "2024-09-01"

[[r2_buckets]]
binding = "PAEBIRU_STORAGE"
bucket_name = "paebiru-storage"

5. Segurança WASM

O SDK utiliza a MacrophageVM para garantir que a execução de plasmídeos no navegador seja totalmente isolada e segura contra vazamento de dados do host. Detalhes adicionais:

  • Sandbox por capability: o WASM é compilado com RUSTFLAGS="-C link-arg=-z stack-size=8388608" e roda com fuel limitado (--fuel 1000000 em wasmtime).
  • Sem syscalls host: o paebiru-c não chama nada fora das APIs expostas via wasm-bindgen. Não há acesso a localStorage, fetch, ou DOM a partir do WASM — apenas via host imports declarados.
  • CSP recomendado: o site hospedeiro deve servir Content-Security-Policy: default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; para que o navegador execute o WASM com a política mínima.
  • COOP/COEP para SharedArrayBuffer: para zero-copy via SharedArrayBuffer, o servidor deve retornar:
    Cross-Origin-Opener-Policy: same-origin
    Cross-Origin-Embedder-Policy: require-corp
    
  • Subresource Integrity (SRI): o paebiru.wasm deve ser carregado com hash SRI para evitar tampering:
    <script type="module">
      import init from '@paebiru/sdk';
      await init(fetch('/paebiru.wasm',
                       { integrity: 'sha384-...' }));
    </script>
    

6. Integração com React, SvelteKit e tRPC

React (CSR + SSR via Next.js)

'use client';
import { useEffect, useState } from 'react';
import { Node, Receipt, MeshEvent } from '@paebiru/sdk';

export function usePaebiru() {
    const [node, setNode] = useState<Node | null>(null);
    const [receipts, setReceipts] = useState<Receipt[]>([]);

    useEffect(() => {
        let cancelled = false;
        (async () => {
            const n = await Node.init({ storage: 'indexeddb' });
            if (cancelled) { await n.close(); return; }
            await n.start();

            n.on('mesh-event', (e: MeshEvent) => {
                if (e.type === 'receipt-produced') {
                    setReceipts((prev) => [...prev, e.receipt]);
                }
            });
            setNode(n);
        })();
        return () => { cancelled = true; node?.close(); };
    }, []);

    return { node, receipts };
}

SvelteKit

<script lang="ts">
  import { onMount } from 'svelte';
  import { Node, type Receipt } from '@paebiru/sdk';

  let receipts: Receipt[] = [];

  onMount(() => {
    const n = Node.init({ storage: 'indexeddb' }).then(async (n) => {
      await n.start();
      n.on('mesh-event', (e) => {
        if (e.type === 'receipt-produced') receipts = [...receipts, e.receipt];
      });
      return n;
    });

    return () => { n.then((nn) => nn.close()); };
  });
</script>

tRPC (type-safe API sobre o nó)

import { initTRPC } from '@trpc/server';
import { z } from 'zod';
import { Node, MeshAddress } from '@paebiru/sdk';

const t = initTRPC.create();
const node = await Node.init({ storage: 'fs:./.paebiru' });
await node.start();

export const appRouter = t.router({
    sendMessage: t.procedure
        .input(z.object({
            target: z.string(),
            payload: z.string(),
        }))
        .mutation(async ({ input }) => {
            const target = MeshAddress.parse(input.target);
            const payload = new TextEncoder().encode(input.payload);
            return await node.sendMessage({ target, payload });
        }),
});

7. Veja também

🐹 Go (paebiru-go)

O binding Go é, entre os 23+ do projeto, o canônico para cloud-native: microsserviços, Kubernetes operators, CLIs estilo Terraform, exporters Prometheus, gRPC services, e sidecars de produção. O Go tem a melhor relação performance/desempenho de engenharia no ecossistema de sistemas distribuídos: binário estático, concorrência nativa via goroutines + channels, e ecossistema rico (prometheus/client_golang, OpenTelemetry, k8s.io/client-go, cobra para CLIs).

O binding usa cgo para vincular paebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com cgo.Handle para gerenciar lifetime de structs C com segurança, runtime.SetFinalizer para cleanup via GC, channels (chan) para stream de eventos, context.Context para cancelamento, e generics (Go 1.18+) para APIs type-safe.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via cgo.Handle: instâncias nativas (nó, identidade, recibo) são representadas como cgo.Handle (um uintptr type-safe) que mapeia para um struct interno contendo o ponteiro C opaco. cgo.Handle permite garbage collection cooperativo entre Go e C — cleanup via cgo.Handle.Delete(handle) ou automático via runtime.SetFinalizer(node, ...) que chama paebiru_node_destroy.
  • Convenção de nomenclatura:
    • Pacotes em lowercase único (paebiru).
    • Tipos em PascalCase (Node, Receipt, MeshEvent).
    • Funções, métodos, variáveis em camelCase (NewNode, sendMessage, nodeID).
    • Constantes em PascalCase ou UPPER_SNAKE (DefaultPort, MAX_PLASMID_SIZE).
    • Interfaces em PascalCase com sufixo -er quando descreve comportamento (MeshEventer).
  • Gerenciamento de memória: defer node.Close() para cleanup imediato; runtime.SetFinalizer para cleanup via GC caso o usuário esqueça. cgo.Handle registra a struct Go↔C com segurança de tipos.
  • Distribuição: módulo Go github.com/paebiru/paebiru-go (importação via go get). CGO_ENABLED=1 por default (necessário para libpaebiru).
  • context.Context para cancelamento: toda operação longa aceita ctx context.Context para cancelamento cooperativo (casa com cancelamento de goroutines via ctx.Done()).
  • Channels para eventos assíncronos: <-chan MeshEvent para consumir eventos da malha — modelagem canônica Go para streams.
  • Generics para type safety (Go 1.18+): EventOf[T any] permite APIs parametrizadas sem interface{} / any poluído.
  • Errors como valores: error interface Go é o canônico; nada de exceções. Wrap com fmt.Errorf("paebiru: %w", err).
  • Testabilidade nativa: testing package para unit tests, testing.B para benchmarks, go test -fuzz para fuzzing.
  • Zero-cópia via unsafe.Pointer: payloads podem ser passados como []byte com slice header apontando para memória C (com unsafe.Slice); alternativa mais segura é copiar via C.GoBytes.

2. Instalação

go get github.com/paebiru/paebiru-go

Pré-requisitos

  • Go ≥ 1.21 (para generics maduros, slices, maps stdlib)
  • CGO_ENABLED=1 (default; necessário para libpaebiru)
  • Sistema: libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows) — instalável via package manager do sistema ou build local

Verificação

// main.go
package main

import (
    "fmt"
    "github.com/paebiru/paebiru-go"
)

func main() {
    version := paebiru.Version()
    fmt.Println("paebiru-go v" + version)
}
go run main.go

3. Exemplo de Uso

Wrapper cgo (o lado C)

// internal/cgo/paebiru_cgo.go
package cgo

/*
#cgo LDFLAGS: -lpaebiru
#include <paebiru.h>
#include <stdlib.h>
#include <string.h>

extern int go_mesh_event_handler(
    void* handle,
    int event_type,
    const char* peer_id,
    size_t peer_id_len,
    const uint8_t* payload,
    size_t payload_len
);
*/
import "C"
import "unsafe"

// Exporta callback Go → C para eventos de malha
//export go_mesh_event_handler
func go_mesh_event_handler(
    handle unsafe.Pointer,
    event_type C.int,
    peer_id *C.char,
    peer_id_len C.size_t,
    payload *C.uint8_t,
    payload_len C.size_t,
) C.int {
    peerID := C.GoStringN(peer_id, C.int(peer_id_len))
    payloadBytes := C.GoBytes(unsafe.Pointer(payload), C.int(payload_len))

    // Despacha para o callback registrado (ver Node.Subscribe)
    globalRegistry.dispatch(handle, int(event_type), peerID, payloadBytes)
    return 0
}

// Declarações C do paebiru-c
//go:linkname paebiru_node_create paebiru_node_create
//golinkname ...

Tipos públicos (API Go idiomática)

// types.go
package paebiru

import "time"

// EventType discrimina variantes de MeshEvent
type EventType int

const (
    EventPeerConnected EventType = iota + 1
    EventPeerLost
    EventReceiptProduced
)

// MeshEvent é a união das variantes de evento da malha
type MeshEvent struct {
    Type      EventType
    PeerID    string
    Timestamp time.Time
    Payload   []byte
    Receipt   *Receipt // populado se Type == EventReceiptProduced
}

// Receipt é o Recibo Soberano
type Receipt struct {
    CID          [32]byte
    CIDHex       string
    MicroJoules  uint64
    IsHealthy    bool
}

// ErrorCode discrimina erros do binding
type ErrorCode int

const (
    ErrOK ErrorCode = iota
    ErrInvalidArgument
    ErrOutOfMemory
    ErrNetworkDown
    ErrUnknown
)

func (e ErrorCode) Error() string {
    switch e {
    case ErrOK:
        return "OK"
    case ErrInvalidArgument:
        return "invalid argument"
    case ErrOutOfMemory:
        return "out of memory"
    case ErrNetworkDown:
        return "network down"
    default:
        return "unknown error"
    }
}

Node com channels, context, sync, finalizer

// node.go
package paebiru

/*
#cgo LDFLAGS: -lpaebiru
#include <paebiru.h>
#include <stdlib.h>
*/
import "C"

import (
    "context"
    "errors"
    "fmt"
    "runtime"
    "sync"
    "time"
    "unsafe"
)

// Node encapsula um nó PAEBIRU
type Node struct {
    handle unsafe.Pointer  // cgo.Handle para o struct C
    cgoID  cgo.Handle      // cgo.Handle para o struct Go (ciclo de vida)

    mu       sync.Mutex
    started  bool
    events   chan MeshEvent
    closed   chan struct{}

    pollCancel context.CancelFunc
}

func NewNode(storagePath string) (*Node, error) {
    cPath := C.CString(storagePath)
    defer C.free(unsafe.Pointer(cPath))

    raw := C.paebiru_node_create(cPath)
    if raw == nil {
        return nil, errors.New("paebiru_node_create returned NULL")
    }

    n := &Node{
        handle: raw,
        events: make(chan MeshEvent, 64),
        closed: make(chan struct{}),
    }

    // cgo.Handle para o struct Go (necessário para callbacks C)
    n.cgoID = cgo.NewHandle(n)

    // Cleanup automático via GC caso usuário esqueça de Close()
    runtime.SetFinalizer(n, func(n *Node) {
        n.Close()
    })

    return n, nil
}

func (n *Node) Start() error {
    n.mu.Lock()
    defer n.mu.Unlock()
    if n.started {
        return nil
    }

    rc := C.paebiru_node_start(n.handle)
    if rc != 0 {
        return fmt.Errorf("paebiru_node_start failed: rc=%d", rc)
    }
    n.started = true

    // Inicia goroutine de polling
    ctx, cancel := context.WithCancel(context.Background())
    n.pollCancel = cancel
    go n.pollLoop(ctx)

    return nil
}

func (n *Node) Close() error {
    n.mu.Lock()
    if !n.started {
        n.mu.Unlock()
        return nil
    }
    n.started = false
    n.mu.Unlock()

    if n.pollCancel != nil {
        n.pollCancel()
    }
    close(n.closed)
    close(n.events)

    C.paebiru_node_destroy(n.handle)
    cgo.DeleteHandle(n.cgoID)
    runtime.SetFinalizer(n, nil)  // remove finalizer (já limpamos)
    return nil
}

func (n *Node) Events() <-chan MeshEvent {
    return n.events
}

func (n *Node) pollLoop(ctx context.Context) {
    ticker := time.NewTicker(100 * time.Millisecond)
    defer ticker.Stop()
    for {
        select {
        case <-ctx.Done():
            return
        case <-ticker.C:
            event, ok := n.pollNextEvent()
            if !ok {
                continue
            }
            select {
            case n.events <- event:
            case <-ctx.Done():
                return
            }
        }
    }
}

func (n *Node) pollNextEvent() (MeshEvent, bool) {
    // Chama C para poll
    var cEvent C.paebiru_event_t
    rc := C.paebiru_node_poll_event(n.handle, &cEvent)
    if rc != 0 {
        return MeshEvent{}, false
    }
    return convertEvent(cEvent), true
}

func (n *Node) SendMessage(ctx context.Context, target string, payload []byte) (*Receipt, error) {
    if err := ctx.Err(); err != nil {
        return nil, err
    }

    cTarget := C.CString(target)
    defer C.free(unsafe.Pointer(cTarget))

    var cReceipt C.paebiru_receipt_t
    rc := C.paebiru_node_send_message(
        n.handle,
        cTarget,
        C.size_t(len(target)),
        (*C.uint8_t)(unsafe.Pointer(&payload[0])),
        C.size_t(len(payload)),
        &cReceipt,
    )
    if rc != 0 {
        return nil, fmt.Errorf("send failed: rc=%d", rc)
    }

    return convertReceipt(cReceipt), nil
}

Programa principal (estilo Go idiomático)

// main.go
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "os/signal"
    "syscall"
    "time"

    "github.com/paebiru/paebiru-go"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // Cria nó (cleanup automático via GC se main() retornar)
    node, err := paebiru.NewNode("./data")
    if err != nil {
        log.Fatal(err)
    }
    defer node.Close()

    if err := node.Start(); err != nil {
        log.Fatal(err)
    }

    // Subscribe a eventos via channel (modelo canônico Go)
    go func() {
        for event := range node.Events() {
            switch event.Type {
            case paebiru.EventPeerConnected:
                fmt.Printf("[peer up]   %s\n", event.PeerID)
            case paebiru.EventPeerLost:
                fmt.Printf("[peer down] %s\n", event.PeerID)
            case paebiru.EventReceiptProduced:
                fmt.Printf("[receipt]   cid=%s µj=%d ok=%v\n",
                    event.Receipt.CIDHex,
                    event.Receipt.MicroJoules,
                    event.Receipt.IsHealthy)
            }
        }
    }()

    // Envia mensagem
    receipt, err := node.SendMessage(ctx, "audit_mesh", []byte("hello from go"))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Receipt CID : %s\n", receipt.CIDHex)
    fmt.Printf("Custo µJ     : %d\n", receipt.MicroJoules)
    fmt.Printf("Algedonic OK : %v\n", receipt.IsHealthy)

    // Aguarda SIGINT para shutdown graceful
    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
    <-sigCh
    log.Println("Shutting down...")
}

4. Integração com gRPC, Prometheus, Kubernetes e CLI

gRPC Server (expor PAEBIRU como API)

Use google.golang.org/grpc para expor o nó como serviço gRPC — ideal para microsserviços:

// proto/paebiru.proto
syntax = "proto3";

package paebiru.v1;

service PaebiruService {
    rpc SendMessage(SendMessageRequest) returns (Receipt);
    rpc StreamEvents(StreamEventsRequest) returns (stream MeshEvent);
}

message SendMessageRequest {
    string target = 1;
    bytes payload = 2;
}

message Receipt {
    bytes  cid = 1;
    string cid_hex = 2;
    uint64 micro_joules = 3;
    bool   is_healthy = 4;
}

message MeshEvent {
    enum Type {
        UNKNOWN = 0;
        PEER_CONNECTED = 1;
        PEER_LOST = 2;
        RECEIPT_PRODUCED = 3;
    }
    Type type = 1;
    string peer_id = 2;
    bytes payload = 3;
    Receipt receipt = 4;
}

message StreamEventsRequest {}
// server.go
package main

import (
    "context"
    "log"
    "net"

    paebirupb "github.com/paebiru/paebiru-go/gen/go/paebiru/v1"

    "google.golang.org/grpc"
)

type server struct {
    paebirupb.UnimplementedPaebiruServiceServer
    node *paebiru.Node
}

func (s *server) SendMessage(ctx context.Context, req *paebirupb.SendMessageRequest) (*paebirupb.Receipt, error) {
    receipt, err := s.node.SendMessage(ctx, req.Target, req.Payload)
    if err != nil {
        return nil, err
    }
    return convertReceiptToProto(receipt), nil
}

func (s *server) StreamEvents(req *paebirupb.StreamEventsRequest, stream paebirupb.PaebiruService_StreamEventsServer) error {
    for event := range s.node.Events() {
        if err := stream.Send(convertEventToProto(event)); err != nil {
            return err
        }
    }
    return nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatal(err)
    }
    s := grpc.NewServer()
    paebirupb.RegisterPaebiruServiceServer(s, &server{node: mustNode()})
    log.Println("gRPC server listening on :50051")
    if err := s.Serve(lis); err != nil {
        log.Fatal(err)
    }
}

func mustNode() *paebiru.Node {
    n, err := paebiru.NewNode("./data")
    if err != nil {
        log.Fatal(err)
    }
    if err := n.Start(); err != nil {
        log.Fatal(err)
    }
    return n
}

Prometheus Exporter (observabilidade da mesh)

Use prometheus/client_golang para expor métricas de mesh (peer count, µJ consumido, recibos produzidos):

// exporter.go
package main

import (
    "log"
    "net/http"
    "time"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"

    "github.com/paebiru/paebiru-go"
)

var (
    peerCount = prometheus.NewGauge(prometheus.GaugeOpts{
        Name: "paebiru_peer_count",
        Help: "Current number of connected peers",
    })
    microJoules = prometheus.NewCounter(prometheus.CounterOpts{
        Name: "paebiru_micro_joules_total",
        Help: "Total microjoules consumed across all operations",
    })
    receiptsProduced = prometheus.NewCounter(prometheus.CounterOpts{
        Name: "paebiru_receipts_produced_total",
        Help: "Total Sober Receipts produced",
    })
    algedonicSignals = prometheus.NewCounterVec(prometheus.CounterOpts{
        Name: "paebiru_algedonic_signals_total",
        Help: "Algedonic signals emitted by type",
    }, []string{"type"})
)

func init() {
    prometheus.MustRegister(peerCount, microJoules, receiptsProduced, algedonicSignals)
}

func main() {
    node, err := paebiru.NewNode("./data")
    if err != nil {
        log.Fatal(err)
    }
    node.Start()
    defer node.Close()

    go func() {
        ticker := time.NewTicker(5 * time.Second)
        defer ticker.Stop()
        var currentPeers int64
        for {
            select {
            case event := <-node.Events():
                switch event.Type {
                case paebiru.EventPeerConnected:
                    currentPeers++
                    peerCount.Set(float64(currentPeers))
                case paebiru.EventPeerLost:
                    currentPeers--
                    peerCount.Set(float64(currentPeers))
                case paebiru.EventReceiptProduced:
                    receiptsProduced.Inc()
                    microJoules.Add(float64(event.Receipt.MicroJoules))
                }
            case <-ticker.C:
                // Refresh stats
            }
        }
    }()

    http.Handle("/metrics", promhttp.Handler())
    log.Println("Prometheus exporter listening on :9100/metrics")
    log.Fatal(http.ListenAndServe(":9100", nil))
}

Kubernetes Operator (operator-sdk)

Use operator-sdk para gerenciar deployments de PAEBIRU no cluster:

// controllers/paebirunode_controller.go
package controllers

import (
    "context"

    "k8s.io/apimachinery/pkg/runtime"
    ctrl "sigs.k8s.io/controller-runtime"
    "sigs.k8s.io/controller-runtime/pkg/client"

    paebiruv1 "github.com/paebiru/paebiru-go/api/v1"
    "github.com/paebiru/paebiru-go/paebiru"
)

type PaebiruNodeReconciler struct {
    client.Client
    Scheme *runtime.Scheme
}

func (r *PaebiruNodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    var pbn paebiruv1.PaebiruNode
    if err := r.Get(ctx, req.NamespacedName, &pbn); err != nil {
        return ctrl.Result{}, client.IgnoreNotFound(err)
    }

    // Reconcilia node PAEBIRU com o spec da CRD
    desired := paebiru.NodeSpec{
        Storage:     pbn.Spec.Storage,
        Listeners:   pbn.Spec.Listeners,
        Replicas:    pbn.Spec.Replicas,
    }
    current := paebiru.NodeStatus{...}

    if !paebiru.Equal(desired, current) {
        // Reconcilia: aplica diff via PAEBIRU
        if err := paebiru.Apply(ctx, r.Client, desired, current); err != nil {
            return ctrl.Result{}, err
        }
    }
    return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
}

CLI (cobra) estilo Terraform/kubectl

Use spf13/cobra para CLI de administração:

// cmd/paebiru/main.go
package main

import (
    "fmt"
    "os"

    "github.com/spf13/cobra"

    "github.com/paebiru/paebiru-go/paebiru"
)

var (
    storagePath string
    rootCmd = &cobra.Command{
        Use:   "paebiru",
        Short: "PAEBIRU node management CLI",
    }
    sendCmd = &cobra.Command{
        Use:   "send [target] [payload]",
        Short: "Send a message to a target peer",
        Args:  cobra.MinimumNArgs(2),
        RunE: func(cmd *cobra.Command, args []string) error {
            n, err := paebiru.NewNode(storagePath)
            if err != nil {
                return err
            }
            defer n.Close()
            if err := n.Start(); err != nil {
                return err
            }
            receipt, err := n.SendMessage(ctx, args[0], []byte(args[1]))
            if err != nil {
                return err
            }
            fmt.Printf("Receipt: %s (µj=%d, ok=%v)\n",
                receipt.CIDHex, receipt.MicroJoules, receipt.IsHealthy)
            return nil
        },
    }
    watchCmd = &cobra.Command{
        Use:   "watch",
        Short: "Stream mesh events",
        RunE: func(cmd *cobra.Command, args []string) error {
            n, err := paebiru.NewNode(storagePath)
            if err != nil {
                return err
            }
            defer n.Close()
            if err := n.Start(); err != nil {
                return err
            }
            for event := range n.Events() {
                fmt.Printf("[%v] peer=%s payload=%v\n",
                    event.Type, event.PeerID, event.Payload)
            }
            return nil
        },
    }
)

func main() {
    rootCmd.PersistentFlags().StringVarP(&storagePath, "storage", "s",
                                          "~/.paebiru", "Storage path")
    rootCmd.AddCommand(sendCmd, watchCmd)
    if err := rootCmd.Execute(); err != nil {
        os.Exit(1)
    }
}
# Uso:
go install github.com/paebiru/paebiru-go/cmd/paebiru@latest
paebiru send audit_mesh "hello"
paebiru watch

Embed (Go 1.16+ embed)

Para distribuir o WASM fallback embutido no binário:

// embed.go
package paebiru

import _ "embed"

//go:embed paebiru.wasm
var paebiruWASM []byte

// Use com `wasmtime-go` para casos onde libpaebiru.so não está disponível
func LoadEmbeddedWASM() ([]byte, error) {
    return paebiruWASM, nil
}

5. Veja também

☕ Java (paebiru-java)

O binding Java integra o PAEBIRU em servidores JVM e em dispositivos Android. Utiliza JNI para chamar o core Rust a partir de uma API idiomática OO, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON, sem reflection em hot-path, sem garbage collection em regiões de latência crítica.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via long: instâncias nativas (nó, identidade, recibo) são representadas por um long de 64 bits que encapsula o ponteiro opaco produzido pelo paebiru-c. A classe Node guarda esse handle em um campo private final long e nunca o expõe fora do JNI.
  • Convenção de nomenclatura: prefixo Paebiru (PascalCase) em classes, métodos em camelCase (JavaBeans), constantes em UPPER_SNAKE_CASE para enums.
  • Gerenciamento de memória: classes que carregam handle nativo implementam AutoCloseable e devem ser usadas com try-with-resources para garantir paebiru_node_destroy mesmo em caso de exceção.
  • Pacote raiz: org.paebiru (reservado; mirror do namespace paebiru no JNI).
  • Sem alocação em hot-path: callbacks registrados via MessageHandler recebem um ByteBuffer direto (zero-copy) alocado pelo lado nativo.

2. Instalação

Aguardando primeira publicação. Quando disponível:

Maven

<dependency>
  <groupId>org.paebiru</groupId>
  <artifactId>paebiru-java</artifactId>
  <version>0.1.0</version>
</dependency>

Gradle (Kotlin DSL)

implementation("org.paebiru:paebiru-java:0.1.0")

A dependência traz a .so/.dylib/.dll correta para a plataforma-alvo via native-loader. Para Android, a lib é empacotada automaticamente em jniLibs/.


3. Exemplo de Uso

import org.paebiru.Node;
import org.paebiru.Receipt;
import org.paebiru.MeshAddress;

public class HelloPaebiru {
    public static void main(String[] args) {
        // try-with-resources garante paebiru_node_destroy
        try (Node node = Node.create("./storage")) {
            node.start();

            // Envia mensagem e recebe Recibo Soberano
            Receipt receipt = node.sendMessage(
                MeshAddress.fromString("12D3KooW..."),
                "hello".getBytes()
            );

            System.out.printf("Receipt CID: %s%n", receipt.cid());
            System.out.printf("Custo µJ:    %d%n", receipt.microJoules());
        } catch (Exception e) {
            // AlgedonicSensor exposto pela API Java
            e.printStackTrace();
        }
    }
}

4. Integração com Android

A lib nativa é distribuída como libpaebiru.so para arm64-v8a, armeabi-v7a, x86_64. Recomendações:

  • Use StrictMode para detectar chamadas bloqueantes vindas do JNI em main thread.
  • Prefira PaebiruAsyncClient (wrapper de coroutines) a bloquear com Future.get().
  • Em background, escute mudanças de topologia via MeshObserver (callback registrado antes de node.start()).
val node = Node.create(context.filesDir.absolutePath + "/paebiru")
node.start()
lifecycleScope.launch {
    node.meshEvents.collect { event ->
        when (event) {
            is MeshEvent.PeerConnected -> log("peer up: ${event.peerId}")
            is MeshEvent.PeerLost     -> log("peer down: ${event.peerId}")
            else -> Unit
        }
    }
}

5. Veja também

🟦 C# (paebiru-csharp)

O binding C# integra o PAEBIRU em qualquer runtime .NET moderno (servidor, MAUI, Unity, Blazor WebAssembly, NativeAOT). Utiliza P/Invoke sobre a base FFI C (paebiru-c) e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON, sem reflection em hot-path, com Span<T>/ReadOnlySpan<T> para evitar cópias intermediárias.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via nuint: instâncias nativas (nó, identidade, recibo) são representadas por nuint (ponteiro nativo opaco) — nunca IntPtr legado. A struct Node guarda esse handle em um campo readonly privado e o expõe ao P/Invoke via nuint quando necessário.
  • Convenção de nomenclatura: prefixo Paebiru (PascalCase) em tipos públicos, métodos em PascalCase (.NET), membros internos em _camelCase (padrão StyleCop).
  • Gerenciamento de memória: tipos que carregam handle nativo implementam IAsyncDisposable (não apenas IDisposable) e devem ser usados com await using para garantir paebiru_node_destroy mesmo em código assíncrono.
  • Pacote raiz: Paebiru.Sdk (reservado).
  • Zero-cópia: payloads de mensagem trafegam como ReadOnlySpan<byte> para o lado nativo; callbacks de hot-path recebem Span<byte> mutável. Nunca alocar byte[] intermediário.
  • Nullable Reference Types: a API pública é totalmente non-nullable; campos opcionais usam T? explicitamente.
  • NativeAOT-friendly: zero reflection em hot-path, zero trimming-bombs; tipos decorados com atributos [DynamicallyAccessedMembers] quando estritamente necessário.

2. Instalação

Aguardando primeira publicação. Quando disponível:

NuGet Package Manager

Install-Package Paebiru.Sdk

.NET CLI

dotnet add package Paebiru.Sdk

PackageReference (csproj)

<ItemGroup>
  <PackageReference Include="Paebiru.Sdk" Version="0.1.0" />
  <NativeReference Include="runtimes/linux-x64/native/libpaebiru.so"
                   Kind="Dynamic" />
</ItemGroup>

A dependência traz o paebiru-c empacotado para todas as plataformas suportadas (linux-x64, linux-arm64, osx-x64, osx-arm64, win-x64, win-arm64, ios, android, wasi-wasm) sob o RID apropriado.


3. Exemplo de Uso

using Paebiru.Sdk;

await using var node = await PaebiruNode.CreateAsync("./storage");
await node.StartAsync();

// Envia mensagem e recebe Recibo Soberano
var receipt = await node.SendMessageAsync(
    target: MeshAddress.Parse("12D3KooW..."),
    payload: "hello"u8 // ReadOnlySpan<byte> via u8 suffix
);

Console.WriteLine($"Receipt CID : {receipt.Cid}");
Console.WriteLine($"Custo µJ     : {receipt.MicroJoules}");
Console.WriteLine($"Algedonic OK : {receipt.IsAlgedonicallyHealthy}");

// Observa eventos de malha (callback com Span, zero-cópia)
node.OnMessageReceived += (peer, payload) =>
{
    // payload é ReadOnlySpan<byte> — alocação só se você chamar .ToArray()
    Console.WriteLine($"msg de {peer}: {payload.Length} bytes");
};

4. Integração com Unity, MAUI e Blazor WASM

A binding C# é a escolha natural para múltiplos alvos graças à portabilidade do .NET. Recomendações:

Unity (motor de jogos, simulação, gêmeos digitais)

  • Use IL2CPP (não Mono) para garantir NativeAOT e compatibilidade com iOS.
  • Em Update()/coroutines, não bloqueie com .Wait() ou .Result; use async UniTask (pacote UniTask) ou jobs Unity para latência determinística.
  • Compartilhe a malha PAEBIRU entre múltiplas cenas via PaebiruNode.CreateAsync em RuntimeInitializeOnLoadMethod.

.NET MAUI (mobile/desktop cross-platform)

  • Em background, use PeriodicTimer para drenar a fila de receipts sem Thread.Sleep.
  • Para Android, marque uses-permission para INTERNET e ACCESS_NETWORK_STATE no AndroidManifest.xml.
  • Para iOS, habilite NSAppTransportSecurity apenas se for comunicar com peers de teste (produção deve usar Noise do libp2p).

Blazor WebAssembly (rodando no navegador)

  • Compile o binding em modo wasi-wasm com NativeAOT.
  • Hot-path de mensagens deve usar IJSUnmarshalledRuntime para passar buffers sem marshalling JS↔.NET.
  • Limite de heap do WASM (~4 GB) impõe batching agressivo para fluxos > 10 msg/s.

5. Veja também

🏛️ Delphi/Object Pascal (paebiru-delphi)

O binding Delphi/Object Pascal é a porta de entrada para sistemas legados de missão crítica (industriais, médicos, financeiros) que precisam integrar o PAEBIRU com décadas de código Object Pascal. O Delphi é uma das poucas linguagens com presença forte simultânea em:

  • Windows desktop (VCL — Visual Component Library)
  • Cross-platform mobile (FMX — FireMonkey)
  • Web servers (Horse, Express, TMS WebCore)
  • Bancos de dados (FireDAC, UniDAC, AnyDAC)
  • Automação industrial (SCADA, PLC, Modbus)

O binding usa a palavra-chave external da Object Pascal para vincular diretamente a libpaebiru via FFI C — sem crate Rust intermediária, similar a Zig e Julia. Segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com Pointer para handles opacos, TBytes para buffers zero-copy, e records com métodos (advanced records) para tipos imutáveis value-type.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via Pointer: instâncias nativas (nó, identidade, recibo) são representadas como Pointer (ponteiro opaco). Encapsuladas em uma classe TPaebiruNode que mantém o handle em um campo private FHandle: Pointer e nunca o expõe fora da unit.
  • Convenção de nomenclatura:
    • Units em Paebiru (singular, sem prefixo u).
    • Classes com prefixo T (TPaebiruNode, TReceipt, TMeshEvent). Tipos exceção com sufixo Exception (EPaebiruError).
    • Métodos e propriedades em PascalCase (Start, SendMessage, MicroJoules).
    • Constantes em UPPER_SNAKE_CASE ou camelCase com prefixo (PAEBIRU_DEFAULT_PORT).
    • Fields privados com prefixo F (FHandle, FStorage).
  • Gerenciamento de memória: classes que carregam handle implementam destructor Destroy; override; (chama paebiru_node_destroy). Em código de chamada, use try ... finally Obj.Free; end; para cleanup garantido.
  • Distribuição: package via GetIt (Embarcadero) ou manualmente via bpl/dcp (Borland Package Library). Para FPC, via fppkg ou git clone.
  • external para FFI C: declaração de funções C com cdecl; external 'paebiru.dll' (Windows) ou external 'libpaebiru.so' (Linux). Calling convention canônico: cdecl.
  • Records com métodos (advanced records): tipos de valor imutáveis como TReceipt, TMeshAddress são record com métodos estáticos (class function) e de instância — sem alocação heap, sem referência.
  • Generics: TList<TReceipt>, TDictionary<string, TMeshEvent> — collections type-safe com zero overhead.
  • Anonymous methods (closures): reference to procedure para callbacks de eventos — mais idiomático que interfaces.
  • TParallel / TTask (Delphi RTL): paralelismo e async/await. TTask.Run para fire-and-forget, await (Delphi ≥ 10.3) para await de TTask.
  • Zero-cópia via Pointer + TBytes: TBytes é array of Byte dynamic; pode ser passada como PByte(@Bytes[0]) para C sem cópia.
  • Atributos (Delphi ≥ 10.3): [Table], [PrimaryKey] para ORM, [Subscribe] para eventos declarativos.
  • UTF-8 nativo: Delphi 2009+ usa string = UnicodeString (UTF-16); convert explicitamente para RawByteString/UTF8String quando chamar C.

2. Instalação

Aguardando primeira publicação. Quando disponível:

Via GetIt Package Manager (Delphi 11+)

Component → GetIt Package Manager → buscar "Paebiru" → Install

Manual (.bpl / .dcp)

// 1. Adicionar ao Library Path do projeto
// Tools → Options → Delphi Options → Library → Library Path
//   C:\paebiru-delphi\Lib\Win64\Release

// 2. Adicionar units ao uses
uses
  Paebiru.Core,
  Paebiru.Mesh,
  Paebiru.Types;

Via Free Pascal (FPC ≥ 3.2.0)

# Instalar a libpaebiru via package manager do sistema
apt install libpaebiru-dev  # Linux
brew install paebiru         # macOS

# Adicionar unit path do binding
fpc -Fu/path/to/paebiru-delphi/units MyApp.pas

Dependências runtime

  • Delphi 11 Alexandria (ou 10.3 Rio mínimo para alguns recursos como atributos e await)
  • Plataforma alvo: Windows 10/11 (x64, ARM64), macOS (Apple Silicon + Intel), iOS, Android, Linux
  • Sistema: paebiru.dll (Windows) / libpaebiru.so (Linux) / libpaebiru.dylib (macOS) — empacotada como .bpl ou bundle Delphi

3. Exemplo de Uso

Declarações FFI (external)

unit Paebiru.FFI;

interface

const
  PAEBIRU_LIB = 'paebiru.dll';  // 'libpaebiru.so' no Linux

type
  // Tipos espelhando paebiru-c
  TPaebiruNodeHandle = type Pointer;
  TPaebiruErrorCode = type Integer;

function paebiru_node_create(const Path: PAnsiChar): TPaebiruNodeHandle;
  cdecl; external PAEBIRU_LIB;

function paebiru_node_start(Handle: TPaebiruNodeHandle): TPaebiruErrorCode;
  cdecl; external PAEBIRU_LIB;

function paebiru_node_send_message(
  Handle: TPaebiruNodeHandle;
  const Target: PAnsiChar;
  Payload: PByte;
  PayloadLen: NativeInt;
  out Receipt: TReceiptBuffer
): TPaebiruErrorCode;
  cdecl; external PAEBIRU_LIB;

procedure paebiru_node_destroy(Handle: TPaebiruNodeHandle);
  cdecl; external PAEBIRU_LIB;

implementation
end.

Classe TPaebiruNode (wrapper OO idiomático)

unit Paebiru.Core;

interface

uses
  System.SysUtils,
  System.Classes,
  System.Threading,
  Paebiru.FFI,
  Paebiru.Types;

type
  TOnMeshEvent = reference to procedure(const Event: TMeshEvent);

  TPaebiruNode = class
  private
    FHandle: TPaebiruNodeHandle;
    FStorage: string;
    FEventHandlers: TArray<TOnMeshEvent>;
    FPollTask: ITask;
    FLock: TObject;
  public
    constructor Create(const AStoragePath: string);
    destructor Destroy; override;

    procedure Start;
    procedure Stop;
    function SendMessage(const ATarget: string;
                         const APayload: TBytes): TReceipt;

    procedure Subscribe(const AHandler: TOnMeshEvent);
    procedure Unsubscribe(const AHandler: TOnMeshEvent);

    property Storage: string read FStorage;
  end;

  EPaebiruError = class(Exception);

implementation

constructor TPaebiruNode.Create(const AStoragePath: string);
begin
  inherited Create;
  FStorage := AStoragePath;
  FLock := TObject.Create;

  // Converte UTF-16 string (Delphi) para UTF-8 PAnsiChar para C
  var AnsiPath := UTF8Encode(FStorage);
  FHandle := paebiru_node_create(PAnsiChar(AnsiPath));
  if FHandle = nil then
    raise EPaebiruError.Create('Failed to create PAEBIRU node');
end;

destructor TPaebiruNode.Destroy;
begin
  Stop;
  if FHandle <> nil then
  begin
    paebiru_node_destroy(FHandle);
    FHandle := nil;
  end;
  FLock.Free;
  inherited Destroy;
end;

procedure TPaebiruNode.Start;
var
  RC: TPaebiruErrorCode;
begin
  RC := paebiru_node_start(FHandle);
  if RC <> 0 then
    raise EPaebiruError.CreateFmt('paebiru_node_start failed: rc=%d', [RC]);

  // Inicia poll loop assíncrono
  FPollTask := TTask.Run(
    procedure
    begin
      while not TTask.CurrentTask.CheckCanceled do
      begin
        var Event := PollNextEvent(Self.FHandle);
        if Event <> nil then
        begin
          TMonitor.Enter(FLock);
          try
            var HandlersCopy := Copy(FEventHandlers);
          finally
            TMonitor.Exit(FLock);
          end;
          for var Handler in HandlersCopy do
            Handler(Event);
        end;
        TThread.Sleep(100);  // 100 ms poll
      end;
    end);
end;

procedure TPaebiruNode.Stop;
begin
  if FPollTask <> nil then
  begin
    FPollTask.Cancel;
    FPollTask.Wait;
    FPollTask := nil;
  end;
end;

function TPaebiruNode.SendMessage(const ATarget: string;
                                  const APayload: TBytes): TReceipt;
var
  AnsiTarget: RawByteString;
  Buffer: TReceiptBuffer;
  RC: TPaebiruErrorCode;
begin
  AnsiTarget := UTF8Encode(ATarget);
  RC := paebiru_node_send_message(
    FHandle,
    PAnsiChar(AnsiTarget),
    PByte(@APayload[0]),   // zero-copy: TBytes → PByte
    Length(APayload),
    Buffer
  );
  if RC <> 0 then
    raise EPaebiruError.CreateFmt('send_message failed: rc=%d', [RC]);
  Result := ReceiptFromBuffer(Buffer);
end;

procedure TPaebiruNode.Subscribe(const AHandler: TOnMeshEvent);
begin
  TMonitor.Enter(FLock);
  try
    FEventHandlers := FEventHandlers + [AHandler];
  finally
    TMonitor.Exit(FLock);
  end;
end;

procedure TPaebiruNode.Unsubscribe(const AHandler: TOnMeshEvent);
begin
  TMonitor.Enter(FLock);
  try
    FEventHandlers := FEventHandlers - [AHandler];
  finally
    TMonitor.Exit(FLock);
  end;
end;

end.

Versão FireMonkey (FMX, cross-platform)

unit MainForm;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.StdCtrls, FMX.Layouts,
  FMX.ListBox, FMX.Memo,
  Paebiru.Core, Paebiru.Types;

type
  TMainForm = class(TForm)
    StartButton: TButton;
    SendButton: TButton;
    TargetEdit: TEdit;
    PayloadEdit: TEdit;
    ReceiptsList: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure StartButtonClick(Sender: TObject);
    procedure SendButtonClick(Sender: TObject);
  private
    FNode: TPaebiruNode;
    procedure HandleMeshEvent(const Event: TMeshEvent);
  end;

var
  MainForm: TMainForm;

implementation

{$R *.fmx}

procedure TMainForm.FormCreate(Sender: TObject);
begin
  // TPath.Combine funciona cross-platform
  FNode := TPaebiruNode.Create(TPath.Combine(TPath.GetDocumentsPath, 'paebiru'));
  FNode.Subscribe(HandleMeshEvent);
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  FNode.Free;  // chama Destroy → paebiru_node_destroy
end;

procedure TMainForm.StartButtonClick(Sender: TObject);
begin
  FNode.Start;
  StartButton.Enabled := False;
  SendButton.Enabled := True;
end;

procedure TMainForm.SendButtonClick(Sender: TObject);
var
  Payload: TBytes;
  Receipt: TReceipt;
begin
  Payload := TEncoding.UTF8.GetBytes(PayloadEdit.Text);
  Receipt := FNode.SendMessage(TargetEdit.Text, Payload);
  ReceiptsList.Items.Add(Format('CID %s  µJ %d  OK=%s',
    [Receipt.CidAsHex, Receipt.MicroJoules, BoolToStr(Receipt.IsAlgedonicallyHealthy, True)]));
end;

procedure TMainForm.HandleMeshEvent(const Event: TMeshEvent);
begin
  TThread.Synchronize(nil,
    procedure
    begin
      ReceiptsList.Items.Add(Format('[%s] %s',
        [Event.TypeName, Event.PeerIdAsString]));
    end);
end;

end.

4. Integração com VCL, Horse (Web) e FireDAC (Database)

VCL (Windows desktop — tradicional)

Use a classe TPaebiruNode em um TService (Delphi DataSnap / RAD Server) para emitir Recibos Soberanos a cada operação crítica:

unit InventoryService;

interface

uses
  System.SysUtils, System.Classes,
  DataSnap.ServerMethodBase,
  Paebiru.Core;

type
  [TRouteService('/inventory')]
  TInventoryService = class(TDataSnapService)
  public
    function CreateItem(const ASKU: string; AQty: Integer): string;
  private
    class var FNode: TPaebiruNode;
  end;

implementation

procedure TInventoryService.Startup;
begin
  FNode := TPaebiruNode.Create('C:\Data\Paebiru');
  FNode.Start;
end;

procedure TInventoryService.Shutdown;
begin
  FNode.Free;
end;

function TInventoryService.CreateItem(const ASKU: string; AQty: Integer): string;
var
  Receipt: TReceipt;
begin
  // Lógica de inventário...
  // (omitida)

  // Emite Recibo Soberano da mutação
  Receipt := FNode.SendMessage('audit_peer',
    TEncoding.UTF8.GetBytes(Format('CREATE sku=%s qty=%d', [ASKU, AQty])));

  Result := Receipt.CidAsHex;
end;

initialization
  TInventoryService.Startup;

finalization
  TInventoryService.Shutdown;

end.

Horse (web framework, estilo Express)

Horse é o framework web Delphi/FPC mais popular, estilo Express.js:

program PaebiruServer;

{$APPTYPE CONSOLE}

uses
  Horse,
  Horse.CORS,
  System.JSON,
  Paebiru.Core, Paebiru.Types;

var
  App: THorse;

begin
  App := THorse.Create;

  App.Use(CORS);

  App.Get('/healthz',
    procedure(Req: THorseRequest; Res: THorseResponse)
    begin
      Res.Send('OK');
    end);

  App.Post('/messages',
    procedure(Req: THorseRequest; Res: THorseResponse)
    var
      Node: TPaebiruNode;
      Body: TJSONObject;
      Receipt: TReceipt;
    begin
      Node := TPaebiruNode.GetInstance;  // singleton global
      Body := Req.BodyJSON;
      Receipt := Node.SendMessage(
        Body.GetValue<string>('target'),
        TEncoding.UTF8.GetBytes(Body.GetValue<string>('payload'))
      );
      Res.Send<TJSONObject>(Receipt.ToJSON);
    end);

  App.Listen(1975);
end.

FireDAC (database integration)

FireDAC é a ORM canônica Delphi. Combine com PAEBIRU para emitir Recibos Soberanos a cada mutação SQL:

procedure TInventoryRepository.SaveItem(const AItem: TItem);
var
  Receipt: TReceipt;
begin
  // Persistência canônica no banco
  FDQueryInsert.ParamByName('sku').AsString := AItem.SKU;
  FDQueryInsert.ParamByName('qty').AsInteger := AItem.Quantity;
  FDQueryInsert.ExecSQL;

  // Emite Recibo Soberano com o CID do registro inserido
  Receipt := FNode.SendMessage('audit_peer',
    TEncoding.UTF8.GetBytes(Format('INSERT %s @%d',
      [AItem.SKU, FDConnection.TxPoint])));
  FLastReceipt := Receipt;
end;

Industrial / SCADA (Modbus, OPC UA)

Delphi tem presença massiva em SCADA/industrial. O binding integra com bibliotecas Modbus (ex: mbusslave) e OPC UA (ex: OPC-UA-Delphi-Library):

unit ModbusToPaebiru;

interface

uses
  ModbusSlave,  // unit do componente Modbus
  Paebiru.Core;

type
  TModbusBridge = class
  private
    FNode: TPaebiruNode;
    FModbus: TModbusSlave;
  public
    constructor Create;
    destructor Destroy; override;
    procedure OnModbusRead(AHoldingRegister: Integer; var AValue: Word);
  end;

implementation

constructor TModbusBridge.Create;
begin
  inherited;
  FNode := TPaebiruNode.Create('/var/lib/paebiru');
  FNode.Start;
  FModbus := TModbusSlave.Create(nil);
  FModbus.OnRead := OnModbusRead;
  FModbus.Active := True;
end;

procedure TModbusBridge.OnModbusRead(AHoldingRegister: Integer;
                                     var AValue: Word);
var
  Payload: TBytes;
  Receipt: TReceipt;
begin
  // Quando o PLC lê um holding register, emite recibo PAEBIRU
  Payload := TEncoding.UTF8.GetBytes(Format('modbus read reg=%d', [AHoldingRegister]));
  Receipt := FNode.SendMessage('scada-audit', Payload);
  AValue := Receipt.MicroJoules mod 65535;  // injeta µJ no modbus
end;

destructor TModbusBridge.Destroy;
begin
  FModbus.Free;
  FNode.Free;
  inherited;
end;

end.

5. Veja também

🛡️ Ada/SPARK (paebiru-ada)

O binding Ada/SPARK é o único entre os 19+ do projeto que pode ser formalmente verificado. Ada é a linguagem canônica para safety-critical — aviação (DO-178C), automotivo (ISO 26262), ferroviário (EN 50128), médico (IEC 62304), defesa (MIL-STD-882), nuclear (IEC 61513) — e SPARK é o subconjunto de Ada com contratos formais e provas matemáticas de ausência de runtime errors, information flow, e correção funcional. O PAEBIRU, com seu ZeroTrustPipeline e Recibo Soberano, casa com Ada/SPARK como uma luva — a segurança que PAEBIRU oferece na rede é complementar à segurança que SPARK oferece no código de cada nó.

O binding usa pragma Import (C, "funcname", "libname") com tipos do pacote Interfaces.C para vincular paebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com tipos privados opacos (private type), Ada.Finalization.Controlled para cleanup determinístico via Finalize chamando paebiru_node_destroy, e tasking nativo (tasks + protected objects) para concorrência first-class.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via private type + Controlled: instâncias nativas (nó, identidade, recibo) são representadas por type Paebiru_Node is new Ada.Finalization.Controlled with private;Controlled garante que Finalize (This : in out Paebiru_Node) é chamado deterministicamente quando o objeto sai de escopo (não depende de GC como ForeignPtr do Haskell). O private esconde o handle C da API pública.
  • Convenção de nomenclatura:
    • Tipos em PascalCase ou Snake_Case_With_Underscores (comunidade Ada usa ambos; estilo GNAT prefere Snake_Case_With_Underscores).
    • Variáveis, constantes, funções em Snake_Case (Storage_Path, Send_Message, Micro_Joules).
    • Packages em PascalCase (Paebiru, Paebiri.Mesh, Paebiri.Receipt).
    • Constantes em Pascal_Case_With_Underscores (não UPPER_SNAKE).
    • Tipos child: Paebiri.Mesh, Paebiri.Receipt, Paebiri.Events.
  • Gerenciamento de memória determinístico: Controlled com Initialize (chama paebiru_node_create) e Finalize (chama paebiru_node_destroy) — sem ambiguidade, sem GC, sem refcount.
  • Distribuição: package Alire (alr install paebiru), index Alire index, ou git via alr with. Para projetos industriais, packages GNAT Pro locais.
  • C interop com Interfaces.C: tipos canônicos (Interfaces.C.Strings.chars_ptr, Interfaces.C.size_t, System.Address) + pragma Convention (C, ...) para chamar funções C com calling convention correta.
  • Tasking first-class: Ada tem tasks (task type Mesh_Task is ... end Mesh_Task;) e protected objects (protected type Mesh_State is ... end Mesh_State;) — concorrência nativa sem bibliotecas externas.
  • Generics (como templates C++ ou generics Rust): generic type Message_Type is private; package Paebiri.Generic_Mesh is ....
  • Contratos formais (Ada 2012+): Pre'Class, Post'Class, Type_Invariant'Class — invariantes de tipo em compile-time.
  • SPARK subset (opcional): pragma SPARK_Mode para marcar subprogramas como verificáveis; pragma Assume, pragma Assert para auxiliar o provador.
  • Ravenscar profile (tasking restrito): pragma Profile (Ravenscar) para alvos hard real-time (sem alocação dinâmica, sem tarefas dinâmicas).
  • Zero-cópia via Interfaces.C.Strings.chars_ptr + Ada.Strings.Bounded (tamanho fixo, sem alocação) + Unchecked_Conversion para reinterpretar memória C.
  • Tipos child com private: encapsulamento rigoroso — apenas a .ads (specification) define a interface pública; a .adb (body) tem a implementação.

2. Instalação

Aguardando primeira publicação no Alire. Quando disponível:

Via Alire (recomendado para projetos novos)

# Instalar Alire (gerenciador de pacotes Ada)
curl -fsSL https://github.com/alire-project/alire/releases/download/v2.0.0/alr-2.0.0-x86_64-linux.tar.gz | tar -xz
export PATH=$PATH:$HOME/alire/bin

# Adicionar índice Alire (já é default)
alr index --add community

# Em seu projeto Ada
cd my-paebiru-app
alr with paebiru
alr build

Via GNAT Project File (gprbuild)

-- my_app.gpr
with "paebiru.gpr";

project My_App is
   for Main use ("main.adb");
   for Source_Dirs use ("src") & Paebiri'Source_Dirs;
   for Object_Dir use "obj";
   for Exec_Dir use "bin";
   for Languages use ("ada", "c");
   package Linker is
      for Default_Switches ("ada") use ("-lpaebiru");
   end Linker;
end My_App;
gprbuild -P my_app.gpr

Verificação

./bin/my_app --healthz

Dependências runtime

  • GNAT Pro 24+ ou GNAT FSF 13+ com Ada 2022 support
  • Alire 2.0+ (recomendado) ou gprbuild manual
  • Sistema: libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows) — linkada via -lpaebiru
  • Opcional: SPARK Pro 24+ ou SPARK FSF 23+ para verificação formal (GNATprove prover)

3. Exemplo de Uso

Especificação (.ads) — interface pública

-- paebiri.ads
with Ada.Finalization;
with Interfaces.C;
with System;

private with Interfaces.C.Strings;

package Paebiri is

   -------------------------
   -- Tipos públicos
   -------------------------

   type Paebiru_Receipt is private;

   type Micro_Joules is new Interfaces.Unsigned_Long_Long;

   type Mesh_Address is new String (1 .. 60);

   -------------------------
   -- Códigos de erro
   -------------------------

   type Error_Code is new Integer range -1 .. 0;

   PAEBIRU_OK  : constant Error_Code := 0;
   PAEBIRU_ERR : constant Error_Code := -1;

   -------------------------
   -- API pública
   -------------------------

   function Create_Node (Storage_Path : String) return Paebiru_Node;

   procedure Start_Node (Node : in out Paebiru_Node);

   procedure Stop_Node (Node : in out Paebiru_Node);

   function Send_Message
     (Node    : in out Paebiru_Node;
      Target  : Mesh_Address;
      Payload : String) return Paebiru_Receipt
     with Pre'Class => Is_Valid (Node);

   function Is_Valid (Node : Paebiru_Node) return Boolean;

private

   -- Tipo opaco (encapsulamento total)
   type Paebiru_Node is new Ada.Finalization.Controlled with record
      Handle : System.Address := System.Null_Address;
   end record;

   overriding procedure Initialize (This : in out Paebiru_Node);
   overriding procedure Finalize   (This : in out Paebiru_Node);

   type Paebiru_Receipt is record
      Cid           : String (1 .. 64);  -- 32 bytes hex
      Micro_Joules  : Micro_Joules := 0;
      Is_Healthy    : Boolean := False;
   end record;

end Paebiri;

Implementação (.adb) — corpo com FFI C

-- paebiri.adb
with Ada.Text_IO;
with Ada.Strings;
with Ada.Strings.Fixed;
with Ada.Exceptions;
with Interfaces.C;
with Interfaces.C.Strings;

package body Paebiri is

   use Ada.Text_IO;
   use Interfaces.C;
   use Interfaces.C.Strings;

   -------------------------
   -- C interop via pragma Import
   -------------------------

   function C_Paebiru_Node_Create
     (Path : chars_ptr) return System.Address
     with Convention => C;
   pragma Import (C, C_Paebiru_Node_Create, "paebiru_node_create");

   procedure C_Paebiru_Node_Start
     (Handle : System.Address; Rc : out C.int)
     with Convention => C;
   pragma Import (C, C_Paebiru_Node_Start, "paebiru_node_start");

   procedure C_Paebiru_Node_Send_Message
     (Handle          : System.Address;
      Target          : chars_ptr;
      Target_Len      : size_t;
      Payload         : System.Address;
      Payload_Len     : size_t;
      Receipt_Out     : System.Address;
      Rc              : out C.int)
     with Convention => C;
   pragma Import (C, C_Paebiru_Node_Send_Message, "paebiru_node_send_message");

   procedure C_Paebiru_Node_Destroy (Handle : System.Address)
     with Convention => C;
   pragma Import (C, C_Paebiru_Node_Destroy, "paebiru_node_destroy");

   -------------------------
   -- Controlled type: Initialize e Finalize determinísticos
   -------------------------

   overriding procedure Initialize (This : in out Paebiru_Node) is
   begin
      This.Handle := System.Null_Address;
   end Initialize;

   overriding procedure Finalize (This : in out Paebiru_Node) is
   begin
      if This.Handle /= System.Null_Address then
         C_Paebiru_Node_Destroy (This.Handle);
         This.Handle := System.Null_Address;
      end if;
   end Finalize;

   -------------------------
   -- Smart constructor
   -------------------------

   function Create_Node (Storage_Path : String) return Paebiru_Node is
      Path_Ptr  : chars_ptr := New_String (Storage_Path & ASCII.NUL);
      New_Node  : Paebiru_Node;
   begin
      New_Node.Handle := C_Paebiru_Node_Create (Path_Ptr);
      Free (Path_Ptr);
      if New_Node.Handle = System.Null_Address then
         raise Program_Error with "paebiru_node_create returned NULL";
      end if;
      return New_Node;
   end Create_Node;

   -------------------------
   -- Start / Stop
   -------------------------

   procedure Start_Node (Node : in out Paebiru_Node) is
      Rc : C.int;
   begin
      C_Paebiru_Node_Start (Node.Handle, Rc);
      if Rc /= 0 then
         raise Program_Error with "paebiru_node_start failed: rc=" & Rc'Img;
      end if;
   end Start_Node;

   procedure Stop_Node (Node : in out Paebiru_Node) is
   begin
      -- Finalize será chamado quando Node sair de escopo;
      -- aqui podemos fazer um "soft stop" antes.
      if Node.Handle /= System.Null_Address then
         -- (C handler opcional: paebiru_node_stop soft)
         null;
      end if;
   end Stop_Node;

   -------------------------
   -- Send_Message com zero-copy
   -------------------------

   function Send_Message
     (Node    : in out Paebiru_Node;
      Target  : Mesh_Address;
      Payload : String) return Paebiru_Receipt
   is
      Target_Ptr  : chars_ptr := New_String (Target & ASCII.NUL);
      Receipt_Out : aliased Paebiru_Receipt := (others => <>);
      Rc          : C.int;
   begin
      -- C_Paebiru_Node_Send_Message espera (handle, target, target_len,
      -- payload, payload_len, receipt_out, rc) — chama com
      -- Payload'Address (zero-copy) e length.
      C_Paebiru_Node_Send_Message
        (Node.Handle,
         Target_Ptr,
         Target_Ptr'Size / 8,  -- chars_ptr size
         Payload'Address,
         Payload'Length,
         Receipt_Out'Address,
         Rc);
      Free (Target_Ptr);

      if Rc /= 0 then
         raise Program_Error with "paebiru_node_send_message failed: rc=" & Rc'Img;
      end if;
      return Receipt_Out;
   end Send_Message;

   function Is_Valid (Node : Paebiru_Node) return Boolean is
   begin
      return Node.Handle /= System.Null_Address;
   end Is_Valid;

end Paebiri;

Versão com task e protected object (concorrência first-class)

-- paebiri_mesh_task.ads
with Paebiri;

package Paebiri.Mesh_Task is

   -- Task dedicada a processar eventos da malha
   task type Event_Handler_Task is
      entry Start (Node : in out Paebiru_Node);
      entry Stop;
   end Event_Handler_Task;

   task body Event_Handler_Task is
      Current_Node : Paebiru_Node;
      Running      : Boolean := False;
   begin
      loop
         select
            accept Start (Node : in out Paebiru_Node) do
               Current_Node := Node;
               Running := True;
            end Start;
         or
            accept Stop do
               Running := False;
            end Stop;
         or
            delay 0.1 when not Running =>
               -- 100 ms poll
               if Running then
                  -- Poll next event from C side
                  declare
                     E : Paebiri.Mesh_Event;
                     Has_Event : Boolean;
                  begin
                     Paebiri.Poll_Event (Current_Node, E, Has_Event);
                     if Has_Event then
                        Put_Line ("[Event] " & Paebiri.Image (E));
                     end if;
                  end;
               end if;
         end select;
      end loop;
   end Event_Handler_Task;

   -- Protected object para estado thread-safe
   protected type Mesh_State is
      procedure Set_Node (N : Paebiru_Node);
      function Get_Node return Paebiru_Node;
      entry Wait_For_Ready;
   private
      The_Node : Paebiru_Node;
      Ready    : Boolean := False;
   end Mesh_State;

end Paebiri.Mesh_Task;
-- paebiri_mesh_task.adb
package body Paebiri.Mesh_Task is

   protected body Mesh_State is
      procedure Set_Node (N : Paebiru_Node) is
      begin
         The_Node := N;
         Ready := True;
      end Set_Node;

      function Get_Node return Paebiru_Node is
      begin
         return The_Node;
      end Get_Node;

      entry Wait_For_Ready when Ready is
      begin
         null;
      end Wait_For_Ready;
   end Mesh_State;

end Paebiri.Mesh_Task;

Versão SPARK com contratos formais (verificação provada)

-- paebiri_spark.ads
package Paebiri.SPARK
  with SPARK_Mode => On
is

   function Send_Message_Verified
     (Node    : in out Paebiru_Node;
      Target  : Mesh_Address;
      Payload : String) return Paebiru_Receipt
     with Pre  => Is_Valid (Node)
                  and then Target'Length > 0
                  and then Payload'Length <= 8192,
          Post => Send_Message_Verified'Micro_Joules >= 0;

   -- Invariante de tipo (SPARK prova em compile-time)
   type Receipt_Collection is private
     with Type_Invariant =>
            (for all R of Self => R.Is_Healthy);

   function Add_Receipt
     (Self : in out Receipt_Collection;
      R    : Paebiru_Receipt) return Boolean
     with Pre  => R.Is_Healthy,
          Post => Add_Receipt'Result = (Self'Length <= 1000);

private

   type Receipt_Array is array (Positive range <>) of Paebiru_Receipt;

   type Receipt_Collection is record
      Items : Receipt_Array (1 .. 1000);
      Last  : Natural := 0;
   end record;

end Paebiri.SPARK;

O provador GNATprove demonstra matematicamente que Send_Message_Verified cumpre seus contratos, sem necessidade de testes runtime.


4. Integração com Avionics (DO-178C), Automotivo (ISO 26262) e Ravenscar

Avionics — DO-178C Design Assurance Level A

Em DO-178C DAL-A (catastrophic failure), cada linha de código é rastreada e coberta por testes formais. Use SPARK + Ravenscar para garantir determinismo temporal:

-- main.adb (avionics)
pragma Task_Dispatching_Policy (FIFO_Within_Priorities);
pragma Locking_Policy (Ceiling_Locking);
pragma Profile (Ravenscar);  -- tasking restrito

with Ada.Real_Time;
with Paebiri;

procedure Avionics_Main is
   -- Período de execução do loop de controle: 10 ms (100 Hz)
   Next_Iteration : Ada.Real_Time.Time :=
     Ada.Real_Time.Clock;
   Period          : constant Ada.Real_Time.Time_Span :=
     Ada.Real_Time.Milliseconds (10);

   Mesh_Node : Paebiri.Paebiru_Node := Paebiri.Create_Node ("/data/paebiru");
begin
   Paebiri.Start_Node (Mesh_Node);

   loop
      -- 1. Lê sensores (omitted)
      -- 2. Processa controle (omitted)
      -- 3. Emite Recibo Soberano a cada ciclo
      declare
         Receipt : Paebiri.Paebiru_Receipt;
      begin
         Receipt := Paebiri.Send_Message
           (Mesh_Node,
            "audit_ground_station",
            "avionics_cycle=" & Ada.Real_Time.Clock'Img);
         -- Log do receipt para auditoria
         Ada.Text_IO.Put_Line ("[DAL-A] Receipt CID: " & Receipt.Cid);
      end;

      -- Aguarda próximo ciclo
      Next_Iteration := Next_Iteration + Period;
      delay until Next_Iteration;
   end loop;
end Avionics_Main;

Automotivo — ISO 26262 ASIL-D

Em ASIL-D (maior nível de safety), use SPARK Mode para provar correção de fluxos críticos (frenagem, direção):

with SPARK.Plus;
with Paebiri;

package body Brake_Controller
  with SPARK_Mode => On
is
   -- Invariante: o nó PAEBIRU é sempre válido
   function Is_Braking_Allowed
     (Speed_Kmh : Natural) return Boolean
     is (Speed_Kmh < 200)  -- limite absoluto
     with Pre  => Speed_Kmh <= 300,
          Post => Is_Braking_Allowed'Result or else not Is_Braking_Allowed'Result;

   -- Toda ação de frenagem gera Recibo Soberano
   procedure Apply_Brakes
     (Node    : in out Paebiri.Paebiru_Node;
      Force_Pct : Natural)
     with Pre  => Is_Valid (Node) and then Force_Pct <= 100
   is
      Receipt : Paebiri.Paebiru_Receipt;
   begin
      -- Aplica frenagem (omitted)
      Receipt := Paebiri.Send_Message
        (Node,
         "v2x_audit",
         "brake force=" & Force_Pct'Img);
   end Apply_Brakes;

end Brake_Controller;

Ravenscar Profile (Hard Real-Time)

Para sistemas hard real-time (sub-millisecond jitter), use Ravenscar que proíbe alocação dinâmica e tarefas criadas em runtime:

pragma Profile (Ravenscar);
pragma Task_Dispatching_Policy (FIFO_Within_Priorities);
pragma Locking_Policy (Ceiling_Locking);
pragma Restrictions (No_Dynamic_Attachment,
                     No_Dynamic_Priorities,
                     No_Task_Allocators,
                     No_Implicit_Dynamic_Code,
                     Max_Asynchronous_Select_Nesting => 1);

Todas as tasks e objetos protegidos são declarados em compile-time, sem alocação dinâmica — perfeito para sistemas embarcados com tempo de resposta determinístico.

Genéricos (typesafe reusable)

generic
   type Message_Type is private;
   with function Serialize (M : Message_Type) return String;
package Paebiri.Generic_Mesh is

   function Send_Typed_Message
     (Node    : in out Paebiri.Paebiru_Node;
      Target  : Paebiri.Mesh_Address;
      Message : Message_Type) return Paebiri.Paebiru_Receipt;

end Paebiri.Generic_Mesh;
package body Paebiri.Generic_Mesh is
   function Send_Typed_Message
     (Node    : in out Paebiri.Paebiru_Node;
      Target  : Paebiri.Mesh_Address;
      Message : Message_Type) return Paebiri.Paebiru_Receipt is
   begin
      return Paebiri.Send_Message (Node, Target, Serialize (Message));
   end Send_Typed_Message;
end Paebiri.Generic_Mesh;

5. Veja também

🎯 Dart (paebiru-dart)

O binding Dart integra o PAEBIRU em Flutter (mobile, web, desktop) e em servidores Dart puros. Utiliza dart:ffi sobre a base FFI C (paebiru-c) e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON, sem reflection em hot-path, com Pointer<Uint8> / Uint8List.view para evitar cópias intermediárias. A camada de domínio expõe Streams nativos do Dart, que casam naturalmente com a metáfora de eventos do Kernel GALS.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via Pointer<Void>: instâncias nativas (nó, identidade, recibo) são representadas por Pointer<Void> opaco. A classe PaebiruNode guarda esse ponteiro em um campo final privado e o expõe ao FFI apenas dentro de métodos @Native isolados.
  • Convenção de nomenclatura: prefixo Paebiru (PascalCase) em tipos públicos, métodos em lowerCamelCase (Effective Dart), constantes em lowerCamelCase (não UPPER_SNAKE).
  • Gerenciamento de memória: o binding expõe close() síncrono e o PaebiruNode implementa o mixin padrão do pacote package:resource para uso com try/finally e with blocks (Dart 3+).
  • Pacote raiz: paebiru (reservado em pub.dev).
  • Null-safety estrita: a API é non-nullable por padrão; opcionais usam T? explicitamente. Sem dynamic em hot-path.
  • Isolates para paralelismo: o binding principal roda no isolate root; cargas pesadas (verificação ZK, deserialização Prolly Tree) devem ser feitas em Worker Isolates com Isolate.spawn para não travar a UI thread.
  • Zero-cópia: payloads de mensagem trafegam como Uint8List.view (vista sobre buffer nativo) ou Pointer<Uint8>. Nunca copiar bytes para Uint8List.fromList em hot-path.
  • Dart 3+ features: usa sealed class para ADTs (ex: Receipt, MeshEvent), record types para tuplas imutáveis, e pattern matching no consumo de mensagens.

2. Instalação

Aguardando primeira publicação. Quando disponível:

Dart puro (servidor, CLI)

dart pub add paebiru

Flutter (mobile, web, desktop)

flutter pub add paebiru

pubspec.yaml manual

dependencies:
  paebiru: ^0.1.0
  # Para hot-path com Workers Isolates:
  resource: ^1.0.0

A dependência traz a libpaebiru.so / .dylib / .dll empacotada para todas as plataformas suportadas via Dart hooks_runner (pub.dev) ou Flutter FFI plugin.


3. Exemplo de Uso

import 'package:paebiru/paebiru.dart';
import 'dart:ffi';
import 'dart:typed_data';

Future<void> main() async {
  // try/finally garante paebiru_node_destroy mesmo em exceção
  final node = await PaebiruNode.create('./storage');
  try {
    await node.start();

    // Subscribe a eventos de malha — Stream é o canônico
    final messages = node.onMessageReceived.listen((event) {
      // event.payload é Uint8List.view — zero-cópia
      print('msg de ${event.peerId}: ${event.payload.length} bytes');
    });

    // Envia mensagem e recebe Recibo Soberano
    final receipt = await node.sendMessage(
      target: MeshAddress.parse('12D3KooW...'),
      payload: Uint8List.fromList('hello'.codeUnits), // hello world
    );

    print('Receipt CID : ${receipt.cid}');
    print('Custo µJ     : ${receipt.microJoules}');
    print('Algedonic OK : ${receipt.isAlgedonicallyHealthy}');

    await messages.cancel();
  } finally {
    node.close();
  }
}

Versão com switch pattern (Dart 3+)

final event = await node.meshEvents.first;
switch (event) {
  case PeerConnected(:final peerId):
    print('peer up: $peerId');
  case PeerLost(:final peerId, reason: final why):
    print('peer down: $peerId ($why)');
  case ReceiptProduced(:final receipt):
    print('receipt: ${receipt.cid}');
}

4. Integração com Flutter e Workers Isolates

Flutter (mobile/web/desktop)

  • Use WidgetsBinding.instance.addPostFrameCallback para não inicializar o nó no meio de um frame (causa jank).
  • Em hot-reload, libere o nó via Refena ou Riverpod lifecycle hook — handles órfãos vazam memória nativa.
  • Para Android, declare permissão <uses-permission android:name="android.permission.INTERNET" />.
  • Para iOS, configure NSLocalNetworkUsageDescription no Info.plist para descoberta mDNS.
  • Para Web, o binding carrega a libpaebiru.wasm via package:web + dart:js_interop; primeira carga é assíncrona (Future.wait([wasmReady, ...])).

Worker Isolates (cargas pesadas)

import 'dart:isolate';

Future<Receipt> verifyReceiptInWorker(Receipt r) async {
  final port = ReceivePort();
  await Isolate.spawn<_VerifyRequest>(
    _verifyEntry,
    _VerifyRequest(r, port.sendPort),
  );
  return await port.first as Receipt;
}

void _verifyEntry(_VerifyRequest req) async {
  // Lógica de verificação ZK no isolate worker — não bloqueia UI
  final verified = await PaebiruNode.current.verifyZkp(req.receipt);
  req.reply.send(verified);
}

5. Veja também

📜 COBOL (paebiru-cobol)

O binding COBOL é o mais politicamente importante para o PAEBIRU entre os 16+ do projeto: COBOL é a língua franca de sistemas bancários, financeiros, previdenciários e governamentais em todo o mundo — e no Brasil em particular. Estima-se que 200-300 bilhões de linhas de COBOL estejam em produção ativa em 2026,processando salários, impostos, transferências PIX, aposentadorias, e folhas de pagamento. O PAEBIRU precisa de uma porta de entrada honesta para esses sistemas — e este binding é essa porta.

O binding usa CALL com cláusulas BY REFERENCE e BY VALUE (GnuCOBOL ≥ 3.0) para invocar funções paebiru-c declaradas em LINKAGE SECTION, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com USAGE POINTER para handles opacos, PIC X(n) para buffers de tamanho fixo, e USAGE BINARY/COMP-3 para inteiros decimais packed (que COBOL manipula nativamente, sem ponto flutuante).

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via USAGE POINTER: instâncias nativas (nó, identidade, recibo) são representadas como USAGE POINTER — o tipo COBOL para ponteiros opacos vindos de C. A LINKAGE SECTION declara o ponteiro, e a working-storage mantém uma cópia (já que LINKAGE é read-only).
  • Convenção de nomenclatura:
    • Variáveis e copybooks em UPPER_SNAKE_CASE ou Hyphenated — convenção COBOL canônica (WS-NODE-HANDLE, WS-PAYLOAD-LEN, LN-PAEBIRU-CALL).
    • Paragraphs em UPPER-HYPHENATED (1000-MAIN-LOGIC, PAEBIRU-SEND-MESSAGE).
    • Programs em Hyphenated (PAEBIRU-CLIENT, BANK-INTEGRATION).
    • Copybooks com prefixo CPY- (convenção) ou extensão .cpy.
    • 88-level conditions para enums: 88 PAEBIRU-OK VALUE 0. 88 PAEBIRU-ERR VALUE 1 THRU 99.
  • Gerenciamento de memória: COBOL não tem malloc/free diretos, mas GnuCOBOL expõe CBL_ALLOC/CBL_FREE da CBL_GC_HOSTED API. Para o handle, o programa declara o ponteiro e a rotina PAEBIRU-DESTROY-NODE chama paebiru_node_destroy via CALL.
  • Distribuição: copybooks (.cpy) + scripts de build (Makefile/CMake) + libpaebiru.so linkado. Não há gerenciador de pacotes COBOL universal — distribuição manual via git, SFTP, ou VSAM dataset.
  • C interop via CALL ... BY VALUE: padrão COBOL 2002, suportado por GnuCOBOL ≥ 3.0. Para alvos legados (IBM COBOL for MVS, etc.), usar BY CONTENT ou BY REFERENCE com WORKING-STORAGE como buffer.
  • Decimal arithmetic nativa: COBOL tem USAGE COMP-3 (packed decimal) — perfeito para MICRO-JOULES e RECEIPT-CID (que pode ser representado como 32 dígitos hex packed). Sem ponto flutuante em hot-path: aritmética financeira com precisão exata.
  • Sequential I/O e indexed files: o binding pode usar ORGANIZATION IS INDEXED (VSAM-like) para armazenar Recibos Soberanos em arquivos ISAM — integração direta com mainframes IBM z/OS.
  • Estrutura de programa: 4 divisões canônicas:
    • IDENTIFICATION DIVISION. — nome do programa
    • ENVIRONMENT DIVISION. — configuração (calls externos)
    • DATA DIVISION.WORKING-STORAGE, LINKAGE, FILE
    • PROCEDURE DIVISION. — lógica
  • PERFORM ao invés de funções: COBOL usa PERFORM paragraph-name para chamar “sub-rotinas” (análogo a funções) — não há function keyword.
  • EVALUATE ao invés de switch: COBOL 85+ tem EVALUATE com WHEN clauses — equivalente estruturado ao switch/case.
  • STRING e INSPECT: manipulação de strings via STRING ... DELIMITED ... INTO ... e INSPECT ... TALLYING/REPLACING/CONVERTING.
  • Inline C via CALL "C" USING: GnuCOBOL permite chamar funções libc diretamente — útil para memcpy, strlen, etc., quando o COBOL puro é verboso demais.

2. Instalação

Aguardando primeira publicação. Quando disponível:

GnuCOBOL (open-source, recomendado)

# Debian/Ubuntu
apt-get install gnucobol libcob4-dev  # ≥ 3.0

# macOS
brew install gnu-cobol

# Compilar
cobc -x -free -o paebiru-client paebiru-client.cbl -lpaebiru

Estrutura de diretórios esperada

/opt/paebiru-cobol/
├── lib/
│   ├── libpaebiru.so         # biblioteca compartilhada
│   └── libpaebiru.a          # biblioteca estática (opcional)
├── include/
│   └── paebiru.h             # header C
├── copybooks/
│   ├── CPY-PAEBIRU.cpy       # declarações de tipos
│   ├── CPY-PAEBIRU-FFI.cpy   # CALLs para funções C
│   └── CPY-PAEBIRU-RECEIPT.cpy
└── examples/
    └── bank-integration.cbl

Makefile (exemplo)

COBC = cobc
COBCFLAGS = -x -free -O2 -I/opt/paebiru-cobol/include
LIBS = -L/opt/paebiru-cobol/lib -lpaebiru

%.exe: %.cbl
	$(COBC) $(COBCFLAGS) -o $@ $< $(LIBS)

Compilação

cobc -x -free -I./copybooks -L/usr/local/lib -l paebiru \
     -o bank-integration bank-integration.cbl

Dependências runtime

  • GnuCOBOL ≥ 3.0 (open-source) — primário
  • libcob4 runtime (parte do GnuCOBOL)
  • libpaebiru.so linkada dinamicamente
  • libc (sempre disponível)
  • Opcional: IBM COBOL for MVS, Micro Focus COBOL, Fujitsu PowerCOBOL — para suporte a alvos mainframe

3. Exemplo de Uso

Copybook: declarações de tipos (CPY-PAEBIRU)

      *>================================================================
      *> CPY-PAEBIRU — declarações de tipos para o binding COBOL
      *>================================================================
      *> Este copybook define as estruturas de dados que espelham
      *> a API C do paebiru. Incluir com COPY CPY-PAEBIRU.
      *>================================================================

      *> Handle opaco do nó PAEBIRU
       01  PAEBIRU-NODE-HANDLE     USAGE POINTER.

      *> Códigos de retorno
       01  PAEBIRU-RETURN-CODE     PIC S9(9) USAGE BINARY.
           88  PAEBIRU-OK               VALUE 0.
           88  PAEBIRU-ERR              VALUE 1 THRU 99.

      *> Identificador do peer de destino (mesh address)
       01  PAEBIRU-PEER-ID         PIC X(60).

      *> Buffer de payload (tamanho fixo para hot-path)
       01  PAEBIRU-PAYLOAD         PIC X(8192).

      *> Tamanho efetivo do payload (em bytes)
       01  PAEBIRU-PAYLOAD-LEN     PIC 9(9) USAGE BINARY.

      *> Recibo Soberano (CausalBlock + assinaturas)
       01  PAEBIRU-RECEIPT.
           05  PAEBIRU-RECEIPT-CID.
               10  FILLER          PIC X(64).  *> 32 bytes hex
           05  PAEBIRU-RECEIPT-MICROJOULES
                                   PIC S9(18) USAGE COMP-3.
           05  PAEBIRU-RECEIPT-HEALTHY
                                   PIC 9(1) USAGE BINARY.
               88  PAEBIRU-HEALTHY      VALUE 1.
               88  PAEBIRU-SICK         VALUE 0.

      *> Evento da malha (polled via PAEBIRU-POLL-EVENT)
       01  PAEBIRU-MESH-EVENT.
           05  PAEBIRU-EVENT-TYPE  PIC X(20).
               88  PAEBIRU-EVT-PEER-CONNECTED
                                   VALUE "PEER_CONNECTED".
               88  PAEBIRU-EVT-PEER-LOST
                                   VALUE "PEER_LOST".
               88  PAEBIRU-EVT-RECEIPT-PRODUCED
                                   VALUE "RECEIPT_PRODUCED".
           05  PAEBIRU-EVENT-DATA  PIC X(512).

Copybook: FFI (CPY-PAEBIRU-FFI)

      *>================================================================
      *> CPY-PAEBIRU-FFI — declarações de CALL para libpaebiru
      *>================================================================

      *> Cria nó PAEBIRU
       01  PAEBIRU-CREATE-ARGS.
           05  PAEBIRU-CREATE-STORAGE-PATH  PIC X(256).

      *> Envia mensagem
       01  PAEBIRU-SEND-ARGS.
           05  PAEBIRU-SEND-HANDLE          USAGE POINTER.
           05  PAEBIRU-SEND-TARGET          PIC X(60).
           05  PAEBIRU-SEND-PAYLOAD         PIC X(8192).
           05  PAEBIRU-SEND-PAYLOAD-LEN     PIC 9(9) USAGE BINARY.
           05  PAEBIRU-SEND-RECEIPT         PIC X(1024).

      *>================================================================
      *> PROCEDURES (chamadas externas)
      *>================================================================

       PROCEDURE DIVISION.

           CALL "paebiru_node_create" USING
               BY REFERENCE PAEBIRU-CREATE-STORAGE-PATH
               BY VALUE     LENGTH OF PAEBIRU-CREATE-STORAGE-PATH
               RETURNING PAEBIRU-NODE-HANDLE
           END-CALL.

           CALL "paebiru_node_start" USING
               BY VALUE PAEBIRU-NODE-HANDLE
               RETURNING PAEBIRU-RETURN-CODE
           END-CALL.

           CALL "paebiru_node_send_message" USING
               BY VALUE PAEBIRU-NODE-HANDLE
               BY REFERENCE PAEBIRU-SEND-TARGET
               BY VALUE     LENGTH OF PAEBIRU-SEND-TARGET
               BY REFERENCE PAEBIRU-SEND-PAYLOAD
               BY VALUE     PAEBIRU-SEND-PAYLOAD-LEN
               BY REFERENCE PAEBIRU-SEND-RECEIPT
               RETURNING PAEBIRU-RETURN-CODE
           END-CALL.

           CALL "paebiru_node_destroy" USING
               BY VALUE PAEBIRU-NODE-HANDLE
           END-CALL.

Programa de exemplo: cliente bancário

      *>================================================================
      *> PAEBIRU-CLIENT — Cliente COBOL que emite Recibos Soberanos
      *>                 de transações bancárias na malha PAEBIRU.
      *>================================================================
      *> Compilar: cobc -x -free -o paebiru-client paebiru-client.cbl -lpaebiru
      *>================================================================

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PAEBIRU-CLIENT.
       AUTHOR. Equipe PAEBIRU.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       REPOSITORY.
           FUNCTION PAEBIRU-NODE-CREATE EXTERNAL AS "paebiru_node_create"
           FUNCTION PAEBIRU-NODE-SEND   EXTERNAL AS "paebiru_node_send_message"
           FUNCTION PAEBIRU-NODE-DESTROY EXTERNAL AS "paebiru_node_destroy".

       DATA DIVISION.
       WORKING-STORAGE SECTION.

       COPY CPY-PAEBIRU REPLACING ==01  PAEBIRU==>==01  WS-PAEBIRU==.

       01  WS-INIT-FLAG             PIC 9(1) VALUE 0.
           88  WS-INITIALIZED            VALUE 1.
           88  WS-NOT-INITIALIZED        VALUE 0.

       01  WS-TRANSACTION-RECORD.
           05  WS-AGENCIA            PIC 9(4) USAGE BINARY.
           05  WS-CONTA              PIC 9(8) USAGE BINARY.
           05  WS-VALOR              PIC S9(13)V99 USAGE COMP-3.
           05  WS-TIPO               PIC X(10).
               88  WS-TIPO-PIX           VALUE "PIX".
               88  WS-TIPO-TED           VALUE "TED".
               88  WS-TIPO-BOLETO        VALUE "BOLETO".

       01  WS-MESSAGE-BUFFER        PIC X(1024).

       PROCEDURE DIVISION.
       0000-MAIN-LOGIC.
           PERFORM 1000-INIT-PAEBIRU
           PERFORM 2000-PROCESS-TRANSACTIONS
           PERFORM 9000-CLEANUP-PAEBIRU
           STOP RUN.

       1000-INIT-PAEBIRU.
      *>    Cria o nó PAEBIRU
           INITIALIZE PAEBIRU-CREATE-STORAGE-PATH
           STRING "/var/lib/paebiru"
               DELIMITED SIZE
               INTO PAEBIRU-CREATE-STORAGE-PATH
           END-STRING

           CALL "paebiru_node_create" USING
               BY REFERENCE PAEBIRU-CREATE-STORAGE-PATH
               RETURNING PAEBIRU-NODE-HANDLE
           END-CALL

           IF PAEBIRU-NODE-HANDLE = NULL
               DISPLAY "ERRO: paebiru_node_create falhou"
               STOP RUN
           END-IF

      *>    Inicia o nó
           CALL "paebiru_node_start" USING
               BY VALUE PAEBIRU-NODE-HANDLE
               RETURNING PAEBIRU-RETURN-CODE
           END-CALL

           IF NOT PAEBIRU-OK
               DISPLAY "ERRO: paebiru_node_start falhou rc=" PAEBIRU-RETURN-CODE
               PERFORM 9000-CLEANUP-PAEBIRU
               STOP RUN
           END-IF

           SET WS-INITIALIZED TO TRUE
           DISPLAY "PAEBIRU-CLIENT: nó inicializado em /var/lib/paebiru"
           .

       2000-PROCESS-TRANSACTIONS.
      *>    Loop principal: lê transações e emite Recibos Soberanos
           PERFORM UNTIL END-OF-FILE
               READ TRANSACTION-FILE INTO WS-TRANSACTION-RECORD
                   AT END SET END-OF-FILE TO TRUE
               END-READ
               IF NOT END-OF-FILE
                   PERFORM 2100-EMIT-RECEIPT
               END-IF
           END-PERFORM
           .

       2100-EMIT-RECEIPT.
      *>    Serializa transação em WS-MESSAGE-BUFFER
           INITIALIZE WS-MESSAGE-BUFFER
           EVALUATE TRUE
               WHEN WS-TIPO-PIX
                   STRING "PIX ag=" WS-AGENCIA " cc=" WS-CONTA
                          " valor=" WS-VALOR
                       DELIMITED SIZE
                       INTO WS-MESSAGE-BUFFER
                   END-STRING
               WHEN WS-TIPO-TED
                   STRING "TED ag=" WS-AGENCIA " cc=" WS-CONTA
                          " valor=" WS-VALOR
                       DELIMITED SIZE
                       INTO WS-MESSAGE-BUFFER
                   END-STRING
               WHEN WS-TIPO-BOLETO
                   STRING "BOLETO ag=" WS-AGENCIA " cc=" WS-CONTA
                          " valor=" WS-VALOR
                       DELIMITED SIZE
                       INTO WS-MESSAGE-BUFFER
                   END-STRING
           END-EVALUATE

      *>    Move mensagem para o buffer PAEBIRU
           MOVE FUNCTION LENGTH(WS-MESSAGE-BUFFER) TO PAEBIRU-SEND-PAYLOAD-LEN
           MOVE WS-MESSAGE-BUFFER TO PAEBIRU-SEND-PAYLOAD

      *>    Define peer de destino
           MOVE "audit_mesh@paebiru.network" TO PAEBIRU-SEND-TARGET

      *>    Envia e recebe Recibo Soberano
           CALL "paebiru_node_send_message" USING
               BY VALUE     PAEBIRU-NODE-HANDLE
               BY REFERENCE PAEBIRU-SEND-TARGET
               BY VALUE     LENGTH OF PAEBIRU-SEND-TARGET
               BY REFERENCE PAEBIRU-SEND-PAYLOAD
               BY VALUE     PAEBIRU-SEND-PAYLOAD-LEN
               BY REFERENCE PAEBIRU-SEND-RECEIPT
               RETURNING PAEBIRU-RETURN-CODE
           END-CALL

           IF PAEBIRU-OK
               DISPLAY "RECIBO: ag=" WS-AGENCIA
                       " cc=" WS-CONTA
                       " valor=" WS-VALOR
                       " rc=" PAEBIRU-RETURN-CODE
           ELSE
               DISPLAY "ERRO envio: ag=" WS-AGENCIA
                       " rc=" PAEBIRU-RETURN-CODE
           END-IF
           .

       9000-CLEANUP-PAEBIRU.
           IF WS-INITIALIZED
               CALL "paebiru_node_destroy" USING
                   BY VALUE PAEBIRU-NODE-HANDLE
               END-CALL
               SET WS-NOT-INITIALIZED TO TRUE
           END-IF
           .

       9999-ERROR-HANDLER.
           DISPLAY "ERRO INESPERADO: " FUNCTION TRIM(ERROR-STATUS)
           PERFORM 9000-CLEANUP-PAEBIRU
           STOP RUN.

      *>================================================================
      *> FILE CONTROL
      *>================================================================
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT TRANSACTION-FILE
               ASSIGN TO "transactions.dat"
               ORGANIZATION IS SEQUENTIAL
               FILE STATUS IS WS-FILE-STATUS.

       DATA DIVISION.
       FILE SECTION.
       FD  TRANSACTION-FILE.
       01  TRANSACTION-RECORD-FILE   PIC X(64).

       WORKING-STORAGE SECTION.
       01  WS-FILE-STATUS           PIC XX.
           88  END-OF-FILE              VALUE "10".

4. Integração com Mainframes, DB2 e VSAM

IBM z/OS Mainframe (IBM COBOL for MVS)

Para integração com mainframes IBM z/OS, o binding usa IBM COBOL for MVS com LINKAGE SECTION apontando para VSAM KSDS files:

      *>================================================================
      *> Recebe arquivo VSAM KSDS de transações (KEY = AGENCIA + CONTA)
      *> Processa cada transação e emite Recibo Soberano via PAEBIRU
      *>================================================================

       IDENTIFICATION DIVISION.
       PROGRAM-ID. VSAMPAEB.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT TRANSACAO-VSAM
               ASSIGN TO TRANSVS
               ORGANIZATION IS INDEXED
               ACCESS MODE IS SEQUENTIAL
               RECORD KEY IS WS-CHAVE-TRANSACAO
               FILE STATUS IS WS-FS-TRANSACAO.

       DATA DIVISION.
       FILE SECTION.
       FD  TRANSACAO-VSAM.
       01  REG-TRANSACAO.
           05  WS-CHAVE-TRANSACAO.
               10  WS-AGENCIA        PIC 9(4).
               10  WS-CONTA          PIC 9(8).
           05  WS-VALOR-TRANSACAO   PIC S9(13)V99 USAGE COMP-3.
           05  WS-DATA-TRANSACAO    PIC 9(8).
           05  WS-TIPO-TRANSACAO    PIC X(3).

       WORKING-STORAGE SECTION.
       COPY CPY-PAEBIRU.

       01  WS-COUNTERS.
           05  WS-CNT-READ          PIC 9(9) VALUE 0.
           05  WS-CNT-EMITTED       PIC 9(9) VALUE 0.
           05  WS-CNT-ERRORS        PIC 9(9) VALUE 0.

       01  WS-BATCH-MESSAGE.
           05  FILLER               PIC X(11)
               VALUE "BATCH END: ".
           05  WS-BATCH-CNT-READ    PIC 9(9).
           05  WS-BATCH-CNT-EMIT     PIC 9(9).

       PROCEDURE DIVISION.
       0000-MAIN.
           PERFORM 1000-INIT-PAEBIRU
           OPEN INPUT TRANSACAO-VSAM
           PERFORM 2000-PROCESS-RECORDS UNTIL END-OF-FILE
           PERFORM 9000-FINALIZE-BATCH
           CLOSE TRANSACAO-VSAM
           PERFORM 9999-CLEANUP
           STOP RUN.

       1000-INIT-PAEBIRU.
           CALL "paebiru_node_create" USING
               BY CONTENT "//DD:PAEBIRU"
               RETURNING PAEBIRU-NODE-HANDLE
           END-CALL
           CALL "paebiru_node_start" USING
               BY VALUE PAEBIRU-NODE-HANDLE
               RETURNING PAEBIRU-RETURN-CODE
           END-CALL
           .

       2000-PROCESS-RECORDS.
           READ TRANSACAO-VSAM
               AT END SET END-OF-FILE TO TRUE
           END-READ
           IF NOT END-OF-FILE
               ADD 1 TO WS-CNT-READ
               PERFORM 2100-EMIT-RECEIPT
           END-IF
           .

       2100-EMIT-RECEIPT.
           INITIALIZE WS-MESSAGE-BUFFER
           STRING "ag=" WS-AGENCIA
                  " cc=" WS-CONTA
                  " valor=" WS-VALOR-TRANSACAO
                  " data=" WS-DATA-TRANSACAO
                  " tipo=" WS-TIPO-TRANSACAO
               DELIMITED SIZE
               INTO WS-MESSAGE-BUFFER
           END-STRING
           MOVE FUNCTION LENGTH(WS-MESSAGE-BUFFER) TO PAEBIRU-SEND-PAYLOAD-LEN
           MOVE WS-MESSAGE-BUFFER TO PAEBIRU-SEND-PAYLOAD
           MOVE "audit_mesh" TO PAEBIRU-SEND-TARGET

           CALL "paebiru_node_send_message" USING
               BY VALUE     PAEBIRU-NODE-HANDLE
               BY REFERENCE PAEBIRU-SEND-TARGET
               BY REFERENCE PAEBIRU-SEND-PAYLOAD
               BY VALUE     PAEBIRU-SEND-PAYLOAD-LEN
               BY REFERENCE PAEBIRU-SEND-RECEIPT
               RETURNING PAEBIRU-RETURN-CODE
           END-CALL

           IF PAEBIRU-OK
               ADD 1 TO WS-CNT-EMITTED
           ELSE
               ADD 1 TO WS-CNT-ERRORS
           END-IF
           .

       9000-FINALIZE-BATCH.
           MOVE WS-CNT-READ TO WS-BATCH-CNT-READ
           MOVE WS-CNT-EMITTED TO WS-BATCH-CNT-EMIT
           DISPLAY WS-BATCH-MESSAGE
           .

DB2 (banco relacional IBM)

Para persistir Recibos Soberanos no DB2 alongside de transações financeiras:

           EXEC SQL
               INSERT INTO PAEBIRU_RECEIPTS (
                   TX_AGENCIA,
                   TX_CONTA,
                   TX_VALOR,
                   PAEBIRU_CID,
                   PAEBIRU_MICROJOULES,
                   PAEBIRU_TIMESTAMP
               ) VALUES (
                   :WS-AGENCIA,
                   :WS-CONTA,
                   :WS-VALOR-TRANSACAO,
                   :PAEBIRU-RECEIPT-CID,
                   :PAEBIRU-RECEIPT-MICROJOULES,
                   CURRENT TIMESTAMP
               )
           END-EXEC
           .

Micro Focus COBOL (Windows/Unix)

Para Micro Focus COBOL (Cobol-IT, Visual COBOL), o binding usa CALL "C:libname" com linkage dinâmico:

           CALL "C$SHARED-LIBRARY" USING
               "paebiru"
               GIVING PAEBIRU-LIB-HANDLE
           END-CALL.

           CALL "C$CALL" USING
               BY REFERENCE "paebiru_node_send_message"
               BY VALUE PAEBIRU-NODE-HANDLE
               BY REFERENCE PAEBIRU-SEND-TARGET
               BY VALUE LENGTH OF PAEBIRU-SEND-TARGET
               BY REFERENCE PAEBIRU-SEND-PAYLOAD
               BY VALUE PAEBIRU-SEND-PAYLOAD-LEN
               BY REFERENCE PAEBIRU-SEND-RECEIPT
               RETURNING PAEBIRU-RETURN-CODE
           END-CALL.

5. Veja também

💧 Elixir (paebiru-elixir)

O binding Elixir é o mais conceitualmente alinhado com o PAEBIRU entre os 14+ do projeto: o BEAM (a VM do Erlang) é literalmente a encarnação industrial do paradigma GALS (Globally Asynchronous, Locally Synchronous). Processos BEAM são localmente síncronos, isolados, leves (milhões em um único nó), e se comunicam globalmente de forma assíncrona via troca de mensagens — exatamente o que o Kernel PAEBIRU faz. Mais: a distribution nativa do Erlang é idêntica ao problema de mesh que o PAEBIRU resolve.

O binding usa a crate Rust Rustler para expor o paebiru-c como NIF (Native Implemented Function), e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com ResourceArc para ownership seguro de structs Rust no BEAM, GenServer para hospedar o estado do nó, e Supervisor para auto-restart em caso de falha algedônica.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via ResourceArc<T>: instâncias nativas (nó, identidade, recibo) são representadas em Rust por T (struct interna), wrappadas em ResourceArc<T> (smart pointer que gerencia refcount entre BEAM e Rust). No lado Elixir, são expostas como references opacas (#Reference<...>) — o BEAM não pode inspecioná-las, apenas passá-las de volta às NIFs.
  • Convenção de nomenclatura:
    • Módulos em PascalCase (Paebiru.Node, Paebiru.Receipt, Paebiru.MeshEvent).
    • Funções em snake_case (start/1, send_message/2, subscribe/2) — estilo Elixir padrão.
    • Variáveis em snake_case (mesh_node, receipt).
    • Átomos canônicos em snake_case ou kebab-case (:connected, :peer_lost, :receipt_produced).
    • Tuplas de retorno: {:ok, value} ou {:error, reason} — convenção Elixir universal.
  • Gerenciamento de memória: ResourceArc<T> decrementa refcount quando a referência Elixir é coletada pelo GC do BEAM; ao chegar a zero, o Drop em Rust chama paebiru_node_destroy. Para cleanup explícito, GenServer.stop(node) é o caminho idiomático.
  • Distribuição: pacote Hex paebiru (reservado).
  • GenServer para o estado do nó: o Paebiru.Node é um GenServer — calls síncronas (GenServer.call), casts assíncronos (GenServer.cast), handle_info para eventos do Kernel. Casa com o KernelActor do PAEBIRU.
  • Padrão de retorno {:ok, _} | {:error, _}: NIFs convertem retornos Rust em tuplas Elixir — facilita pattern matching e pipe.
  • Pattern matching: o consumidor usa case e match? em vez de if/else. Tipo de erro é parte do tipo de retorno (sem exceções).
  • Pipe operator: encadeamento de operações via |> é o canônico Elixir — node |> start_node() |> send_message(...).
  • Zero-cópia via binary: payloads entram/saem como binary (que é u8[] zero-copy no BEAM). Para fluxos

    10 MB, use NIF stream com OwnedEnv.

  • Distribution: o binding integra nativamente com :net_kernel (distribution Erlang) — peer_id PAEBIRU pode ser mapeado para um <node>@<host> Erlang.

2. Instalação

Aguardando primeira publicação no Hex. Quando disponível:

mix.exs (padrão Mix)

defp deps do
  [
    {:paebiru, "~> 0.1.0"}
  ]
end
mix deps.get
mix compile

mix.exs (com Rustler pré-compilado — opcional)

defp deps do
  [
    {:paebiru, "~> 0.1.0"},
    {:rustler, "~> 0.31", runtime: false, optional: true}
  ]
end

Verificação

mix run -e 'IO.inspect(Paebiru.version())'

Dependências runtime

  • Elixir ≥ 1.15 (para mix rustler, NIF 2.14, Logger.metadata)
  • OTP ≥ 26 (para Logger.format_metadata/1, Process.send_after/3 melhorias)
  • Sistema: libpaebiru.so / .dylib / .dll — distribuída como precompiled NIF via RustlerPrecompiled (sem toolchain Rust no consumidor final)

3. Exemplo de Uso

API básica (GenServer + pattern matching + pipe)

# lib/my_app/mesh.ex
defmodule MyApp.Mesh do
  use GenServer
  alias Paebiru.{Node, Receipt, MeshEvent}

  # --- API pública ---

  def start_link(opts \\ []) do
    GenServer.start_link(__MODULE__, opts, name: __MODULE__)
  end

  def send_message(peer_id, payload) do
    GenServer.call(__MODULE__, {:send_message, peer_id, payload})
  end

  def subscribe(handler) do
    GenServer.cast(__MODULE__, {:subscribe, handler})
  end

  # --- Callbacks GenServer ---

  @impl true
  def init(opts) do
    state = Node.new!(Keyword.get(opts, :storage_path, "~/.paebiru"))
    {:ok, %{node: state, subscribers: []}, {:continue, :start}}
  end

  @impl true
  def handle_continue(:start, %{node: node} = state) do
    :ok = Node.start(node)
    Process.send_after(self(), :poll_events, 100)
    {:noreply, state}
  end

  @impl true
  def handle_call({:send_message, peer_id, payload}, _from, %{node: node} = state) do
    case Node.send_message(node, peer_id, payload) do
      {:ok, receipt} -> {:reply, {:ok, receipt}, state}
      {:error, reason} -> {:reply, {:error, reason}, state}
    end
  end

  @impl true
  def handle_cast({:subscribe, handler}, state) do
    {:noreply, %{state | subscribers: [handler | state.subscribers]}}
  end

  @impl true
  def handle_info(:poll_events, state) do
    state = drain_events(state)
    Process.send_after(self(), :poll_events, 100)
    {:noreply, state}
  end

  defp drain_events(state) do
    case Node.next_event(state.node, 0) do
      {:ok, nil} -> state
      {:ok, event} ->
        Enum.each(state.subscribers, &dispatch(&1, event))
        drain_events(state)
      {:error, _} -> state
    end
  end

  defp dispatch(handler, %MeshEvent{} = event), do: handler.(event)
end

Versão com with (pipe-friendly error handling)

def send_to_coordinator(payload) do
  with {:ok, node} <- ensure_started(),
       {:ok, receipt} <- Paebiru.Node.send_message(node, "coordinator", payload) do
    Logger.info("receipt: cid=#{receipt.cid} µj=#{receipt.micro_joules}")
    {:ok, receipt}
  else
    {:error, reason} -> Logger.error("send failed: #{inspect(reason)}")
  end
end

Versão com case + pattern matching em MeshEvent

def handle_event(%MeshEvent{type: :peer_connected, peer_id: id}) do
  Logger.info("peer up: #{id}")
end

def handle_event(%MeshEvent{type: :peer_lost, peer_id: id, reason: why}) do
  Logger.warning("peer down: #{id} (#{why})")
end

def handle_event(%MeshEvent{type: :receipt_produced, receipt: r}) do
  Logger.info("receipt: #{r.cid}")
end

4. Integração com Phoenix, Nerves e :net_kernel

Phoenix (web + LiveView)

  • Crie um PaebiruWeb.MeshChannel para streamar eventos PAEBIRU em tempo real para o frontend:
    defmodule PaebiruWeb.MeshChannel do
      use Phoenix.Channel
    
      def join("mesh:" <> topic, _params, socket) do
        send(self(), :after_join)
        {:ok, socket}
      end
    
      def handle_info(:after_join, socket) do
        MyApp.Mesh.subscribe(fn event ->
          push(socket, "mesh_event", Paebiru.Encoder.encode(event))
        end)
        {:noreply, socket}
      end
    end
    
  • Em app.js, escute via channel.on("mesh_event", ...) e atualize LiveView assigns — o frontend recebe Cada recibo Soberano em < 100 ms.
  • Exponha REST em router.ex para enviar mensagens:
    scope "/api", PaebiruWeb do
      post "/messages", MessageController, :create
    end
    
    def create(conn, %{"target" => target, "payload" => payload}) do
      with {:ok, receipt} <- MyApp.Mesh.send_message(target, payload) do
        json(conn, %{receipt: receipt})
      end
    end
    

Nerves (embarcado / IoT — perfeito para MuleNodes!)

Nerves é a stack canônica Elixir para embarcados. O binding PAEBIRU + Nerves é a combinação ideal para MuleNodes que rodam LoRa/ATmega em campo:

# mix.exs
defp deps do
  [
    {:nerves, "~> 1.10", runtime: false},
    {:paebiru, "~> 0.1.0"},
    {:nerves_lora, "~> 0.3"}  # driver SX1262
  ]
end
# lib/mule_node.ex
defmodule MuleNode do
  use Nerves.Runtime
  alias Paebiru.Node

  def start(_type, _args) do
    children = [
      {Node, storage_path: "/root/.paebiru", transport: :lora}
    ]
    Supervisor.start_link(children, strategy: :one_for_one)
  end
end

A imagem Nerves roda em Raspberry Pi Zero, BeagleBone, ou custom boards com chip LoRa — e expõe a malha PAEBIRU via WiFi/Ethernet/LoRa com o mesmo protocolo do nó “grande”.

:net_kernel (distribution Erlang ↔ mesh PAEBIRU)

A distribution Erlang é a predecessora histórica do problema que o PAEBIRU resolve. Mapeamento direto:

Conceito PAEBIRUConceito Erlang
PeerId<node>@<host> (ex: node1@192.168.1.10)
GossipSub:rpc.call / :gen_server.cast
MeshEventProcess (cada peer = um processo)
ReceiptMessage enviada entre processos
Discovery (mDNS)EPMD (Erlang Port Mapper Daemon)

Para iniciar um nó PAEBIRU distribuído:

Node.start(:"paebiru@#{:inet.gethostname()}",
          :longnames,
          [:"paebiru@192.168.1.10"])

E RPC diretamente entre nós:

:rpc.call(:paebiru@node2, MyApp.Mesh, :send_message, ["target", "hello"])

Hot code reload (OTA updates!)

O BEAM recompila módulos em runtime sem parar processos — combine com update_plasmid do PAEBIRU para fazer OTA de plasmídeos WASM sem parar o nó:

# lib/ota.ex
defmodule MyApp.OTA do
  def update_plasmid(plasmid_wasm_bytes) do
    :ok = MyApp.Mesh.send_message("coordinator", {:update, plasmid_wasm_bytes})

    # Em paralelo, BEAM recarrega o módulo Elixir correspondente
    Code.compile_string(File.read!("lib/plasmids/handler.ex"))
    Logger.info("plasmídeo + handler recarregados sem parar o nó")
  end
end

Supervisão (auto-restart em falha algedônica)

# lib/my_app/application.ex
defmodule MyApp.Application do
  use Application

  def start(_type, _args) do
    children = [
      # Restart 'normal' (não 'transient'/'temporary') para hot-reload
      MyApp.Mesh,
      # Reinicia após backoff exponencial se Mesh falhar
      {Task.Supervisor, name: MyApp.TaskSupervisor}
    ]

    opts = [strategy: :one_for_one, max_restarts: 3]
    Supervisor.start_link(children, opts)
  end
end

Quando o AlgedonicSensor do PAEBIRU dispara Veto Algedônico, o processo BEAM vinculado ao nó recebe :exit com reason específica. O Supervisor reinicia o MyApp.Mesh automaticamente — fail-stop em escala fractal funcionando no nível do runtime.


5. Veja também

λ Haskell (paebiru-haskell)

O binding Haskell é, entre os 18+ do projeto, o que tem o casamento conceitual mais profundo com PAEBIRU além do Elixir — mas por um caminho diferente. Enquanto Elixir casa pelo modelo de atores do BEAM (GALS), Haskell casa pela pureza funcional + sistema de tipos: o PAEBIRU expressa invariantes algedônicas e de Causalidade que Haskell pode verificar em compile-time via tipos (tipos dependentes leves, GADTs, type families). Mais: a abstração canônica de processos distribuídos em Haskell acadêmico é o distributed-process (Cloud Haskell), que mapeia diretamente para MeshEvent e processos PAEBIRU.

O binding usa foreign import capi (FFI para C, com marshaling de tipos via Storable) para vincular paebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com ForeignPtr (com finalizer) para ownership seguro de handles C, ByteString para buffers zero-copy, e Maybe/Either para tratar null/erros sem null em runtime.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via ForeignPtr com finalizer: instâncias nativas (nó, identidade, recibo) são representadas por data PaebiruNode = PaebiruNode {-# UNPACK #-} !(ForeignPtr CPaebiruNode). O ForeignPtr gerencia refcount e dispara um finalizer registrado via Foreign.newForeignPtr que chama paebiru_node_destroy quando o GC de Haskell coleta o último reference — análogo a Rc<T> com Drop em Rust.
  • Convenção de nomenclatura:
    • Tipos, construtores em PascalCase (PaebiruNode, Receipt, MeshEvent, PeerConnected).
    • Funções em camelCase (startNode, sendMessage, subscribeEvents).
    • Variáveis e funções locais em camelCase ou snake_case (comunidade dividida; moderno é camelCase).
    • Tipos ADT e de erro: data PaebiruError = NetworkError | OutOfMemory | Unknown | ...
    • Módulos em PascalCase (Network.Paebiru.Mesh).
  • Gerenciamento de memória: ForeignPtr + finalizer cuida de cleanup automático. Para cleanup imediato, withForeignPtr permite escopo léxico com cleanup determinístico.
  • Distribuição: pacote Hackage paebiru (reservado). Documentação via Haddock.
  • Pureza funcional: funções puras onde possível, IO apenas para side effects (C interop, I/O). Zero unsafePerformIO em código de aplicação — apenas dentro do binding (necessário para chamar C).
  • Type classes para abstração:
    class ToBytes a where
      toBytes :: a -> ByteString
    class FromBytes a where
      fromBytes :: ByteString -> Either String a
    
    Permite que tipos PAEBIRU e tipos de usuário implementem serialização canônica.
  • ADTs para eventos e erros:
    data MeshEvent
      = PeerConnected !PeerId
      | PeerLost !PeerId !DisconnectReason
      | ReceiptProduced !Receipt
      deriving (Show, Eq, Generic)
    
    data PaebiruError
      = InvalidArgument String
      | OutOfMemory
      | NetworkError
      | UnknownCError !CInt
      deriving (Show, Eq, Exception)
    
  • Maybe para null, Either para erro: sem null em runtime; o sistema de tipos força tratamento explícito.
  • ByteString para buffers binários: muito mais eficiente que String (lazy) ou Data.ByteString.Char8 para I/O binário. ByteString é o TBytes de Haskell.
  • Text para strings Unicode: eficiente (packed UTF-16 array) e O(1) length, vs String lazy.
  • Storable typeclass: implementada por todos os tipos que atravessam fronteira FFI — permite peek/poke type-safe via with / alloca / peekByteOff.
  • Type safety no compile-time: tipos GADTs e DataKinds (lightweight dependent types) garantem invariantes em compile-time, não runtime.

2. Instalação

Aguardando primeira publicação no Hackage. Quando disponível:

Via Cabal (recomendado)

cabal update
cabal install paebiru
# stack.yaml
extra-deps:
  - paebiru-0.1.0
stack install paebiru

Em cabal.project (para projetos downstream)

source-repository-package
  type: git
  location: https://github.com/paebiru/paebiru-haskell
  tag: v0.1.0

Verificação

cabal run paebiru-demo

Dependências runtime

  • GHC ≥ 9.4 (Glasgow Haskell Compiler)
  • cabal-install ≥ 3.10 (recomendado) ou stack ≥ 2.13
  • Sistema: libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows) — distribuída como parte do Hackage package (auto-detect via extra-libraries)
  • libc (sempre disponível)

3. Exemplo de Uso

Definições FFI (foreign import capi)

-- src/Paebiru/FFI.hs
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE CApiFFI #-}  -- GHC 9.2+: type-safe C API

module Paebiru.FFI where

import Foreign.Ptr (Ptr, FunPtr, nullPtr)
import Foreign.C.Types
import Foreign.C.String
import Foreign.Storable
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BSU

-- Tipo opaco C
data CPaebiruNode

-- Função C: cria nó (retorna Ptr C)
foreign import capi safe "paebiru.h paebiru_node_create"
  c_paebiru_node_create :: CString -> IO (Ptr CPaebiruNode)

-- Função C: inicia nó
foreign import capi safe "paebiru.h paebiru_node_start"
  c_paebiru_node_start :: Ptr CPaebiruNode -> IO CInt

-- Função C: envia mensagem
foreign import capi safe "paebiru.h paebiru_node_send_message"
  c_paebiru_node_send_message
    :: Ptr CPaebiruNode
    -> CString -> CSize         -- target
    -> Ptr Word8 -> CSize       -- payload + length
    -> Ptr CReceiptBuffer       -- receipt out
    -> IO CInt

-- Função C: destrói nó
foreign import capi safe "paebiru.h paebiru_node_destroy"
  c_paebiru_node_destroy :: Ptr CPaebiruNode -> IO ()

-- Estrutura C espelhada
data CReceiptBuffer = CReceiptBuffer
  { crbCid           :: !(Ptr Word8)  -- 32 bytes
  , crbMicroJoules   :: !Word64
  , crbIsHealthy     :: !Word8
  }

Wrapper type-safe (sem raw pointers na API pública)

-- src/Paebiru/Core.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Paebiru.Core where

import Control.Exception (Exception, throwIO, catch, bracket)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BSU
import Data.Word (Word8, Word64)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import Data.Coerce (coerce)
import Foreign.Ptr (Ptr, nullPtr, castPtr)
import Foreign.ForeignPtr
  ( ForeignPtr, newForeignPtr, withForeignPtr )
import Foreign.Concurrent (newForeignPtr)  -- thread-safe
import qualified Foreign.Marshal.Alloc as FMA
import qualified Foreign.Marshal.Array as FMe
import qualified Data.ByteString as BS
import Data.Default (Default, def)
import GHC.Generics (Generic)

import Paebiru.FFI
import Paebiru.Types
import Paebiru.Events

-- Tipo público: ForeignPtr com finalizer
newtype PaebiruNode = PaebiruNode (ForeignPtr CPaebiruNode)
  deriving stock (Generic)

-- Smart constructor com finalizer
createNode :: FilePath -> IO PaebiruNode
createNode storagePath = do
  -- Converte FilePath para CString UTF-8
  BS.useAsCString (TE.encodeUtf8 (T.pack storagePath)) $ \cPath -> do
    rawPtr <- c_paebiru_node_create cPath
    if rawPtr == nullPtr
      then throwIO $ InvalidArgument "paebiru_node_create returned NULL"
      else do
        -- ForeignPtr com finalizer: chama paebiru_node_destroy
        fp <- newForeignPtr c_paebiru_node_destroy rawPtr
        return (PaebiruNode fp)

-- startNode: ação, mas type-safe
startNode :: PaebiruNode -> IO ()
startNode (PaebiruNode fp) = withForeignPtr fp $ \ptr -> do
  rc <- c_paebiru_node_start ptr
  unless (rc == 0) $
    throwIO $ UnknownCError rc

-- sendMessage com zero-copy
sendMessage
  :: PaebiruNode
  -> Text           -- target
  -> ByteString     -- payload
  -> IO Receipt
sendMessage (PaebiruNode fp) target payload =
  withForeignPtr fp $ \ptr -> do
    -- Aloca receipt buffer no C heap
    receiptBuf <- FMA.allocaBytes 64 $ \buf -> do
      -- target como CString (zero-copy onde possível)
      BS.useAsCString (TE.encodeUtf8 target) $ \cTarget -> do
        -- payload: zero-copy com BSU.unsafeUseAsCString
        BSU.unsafeUseAsCStringLen payload $ \(cPayload, cPayloadLen) -> do
          rc <- c_paebiru_node_send_message
                   ptr
                   cTarget (fromIntegral $ BS.length (TE.encodeUtf8 target))
                   (castPtr cPayload) (fromIntegral cPayloadLen)
                   buf
          unless (rc == 0) $
            throwIO $ UnknownCError rc
          receiptFromBuffer buf
    return receiptBuf

-- Cleanup via ForeignPtr: AUTOMÁTICO quando GC coleta
-- Para cleanup imediato:
destroyNode :: PaebiruNode -> IO ()
destroyNode (PaebiruNode fp) = finalizeForeignPtr fp

Versão Cloud Haskell (distributed-process)

O casamento mais elegante: PAEBIRU + distributed-process:

-- src/Paebiru/Cloud.hs
{-# LANGUAGE TemplateHaskell #-}

module Paebiru.Cloud where

import Control.Distributed.Process
import Control.Distributed.Process.Closure
import Control.Distributed.Process.Node
import Network.Transport.TCP (createTransport, defaultTCPParameters)
import qualified Data.ByteString.Lazy as BL

import Paebiru.Core
import Paebiru.Events

-- Mensagens do protocolo PAEBIRU ↔ Cloud Haskell
data MeshMsg
  = SendMsg Text BL.ByteString (Process Receipt)
  | Subscribe (EventChannel -> Process ())
  | BroadcastReceipt Receipt
  deriving (Typeable, Show)

-- MeshEvent como channel tipado
type EventChannel = SendPort MeshEvent

-- Ator "MeshNode" em Cloud Haskell — pode rodar em qualquer nó do cluster
meshNodeProcess :: FilePath -> Process ()
meshNodeProcess storage = do
  -- Inicializa nó PAEBIRU (ForeignPtr com finalizer)
  liftIO $ createNode storage >>= startNode
  -- Cria channel para assinantes
  (sendPort, recvPort) = newChan
  -- Loop principal
  forever $ do
    msg <- receiveChan recvPort
    case msg of
      SendMsg target payload replyTo -> do
        receipt <- liftIO $ sendMessage
          (PaebiruNode undefined)  -- in real code: store as state
          target (BL.toStrict payload)
        send replyTo receipt
      Subscribe handler -> do
        -- Handler recebe cópia do sendPort
        _ <- fork $ handler sendPort
        return ()
      _ -> return ()
  where
    PaebiruNode undefined = error "real state would be threaded"

-- Função para iniciar nó PAEBIRU em cluster Cloud Haskell
startMeshCluster :: FilePath -> String -> Int -> IO ()
startMeshCluster storage host port = do
  Right transport <- createTransport (show host) (show port) []
  node <- newLocalNode transport initRemoteTable
  runProcess node $ meshNodeProcess storage

Versão com Either para error handling (idiomático Haskell)

-- Versão com Either em vez de throwIO
sendMessageSafe
  :: PaebiruNode
  -> Text
  -> ByteString
  -> IO (Either PaebiruError Receipt)
sendMessageSafe node target payload = do
  result <- try (sendMessage node target payload) :: IO (Either PaebiruError Receipt)
  return result
  where
    try :: IO a -> IO (Either e a)
    try = Control.Exception.try

-- Uso:
result <- sendMessageSafe node "audit_peer" "hello"
case result of
  Right receipt -> putStrLn $ "OK: " ++ show receipt
  Left err      -> putStrLn $ "ERR: " ++ show err

Versão com tipos mais precisos (GADTs)

-- | Tipo-família para tags de evento (lightweight dependent types)
data EventTag = PeerConnectedTag | PeerLostTag | ReceiptProducedTag

-- | ADT parametrizada pelo tag (GADT)
data TaggedEvent (tag :: EventTag) where
  PeerConnectedEv   :: PeerId -> TaggedEvent 'PeerConnectedTag
  PeerLostEv        :: PeerId -> DisconnectReason -> TaggedEvent 'PeerLostTag
  ReceiptProducedEv :: Receipt -> TaggedEvent 'ReceiptProducedTag

-- Type class para pattern matching exaustivo
class EventPayload (tag :: EventTag) where
  unwrap :: TaggedEvent tag -> ... -- específico de cada tag

4. Integração com WAI (Web), QuickCheck e Cloud Haskell

WAI/Warp (servidor HTTP)

Use WAI + Warp para servir API REST de observabilidade:

-- src/Paebiru/Web.hs
{-# LANGUAGE OverloadedStrings #-}

module Paebiru.Web where

import Network.Wai
import Network.Wai.Handler.Warp
import Network.HTTP.Types (status200, status400, status500)
import Data.Aeson (encode, toJSON, object, (.=))
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS8

import Paebiru.Core
import Paebiru.Events

-- | Handler para POST /messages
handleSendMessage :: PaebiruNode -> Request -> IO Response
handleSendMessage node req = do
  body <- strictRequestBody req
  case parseRequest body of
    Just (target, payload) -> do
      result <- sendMessageSafe node target payload
      case result of
        Right receipt -> return $ responseLBS status200 [("Content-Type", "application/json")] (encode receipt)
        Left err      -> return $ responseLBS status500 [] (encode err)
    Nothing -> return $ responseLBS status400 [] "Bad request"

-- | Server
runMeshServer :: FilePath -> Int -> IO ()
runMeshServer storage port = do
  node <- createNode storage
  startNode node
  let app = handleSendMessage node
  run port app
  where
    parseRequest bs = ...

QuickCheck (property-based testing)

QuickCheck é a ferramenta canônica Haskell para property-based testing — perfeita para testar invariantes do ZeroTrustPipeline:

-- test/PaebiruSpec.hs
{-# LANGUAGE ScopedTypeVariables #-}

module Main where

import Test.QuickCheck
import qualified Data.ByteString as BS
import qualified Data.Text as T

import Paebiru.Core
import Paebiru.Events

main :: IO ()
main = do
  -- Setup nó PAEBIRU uma vez
  node <- createNode "/tmp/paebiru-test"
  startNode node

  -- Property: enviar + receber é associativo (mesma sequência ⇒ mesmos CIDs)
  quickCheck $ \payloads ->
    let messages = map (\p -> ("peer-a", BS.pack p)) payloads
        -- Envia todos e coleta CIDs
        cids = map (\(t, p) -> sendMessage node (T.pack t) p) messages
    in all (\receipt -> receiptIsValid receipt) cids

  where
    receiptIsValid r = receiptMicroJoules r > 0

-- Property: Recibo Soberano tem CID de tamanho fixo (32 bytes)
prop_cid_length :: Receipt -> Bool
prop_cid_length r = BS.length (receiptCid r) == 32

-- Property: Algedonic flag é consistente
prop_algedonic_consistency :: Receipt -> Bool
prop_algedonic_consistency r =
  (receiptIsAlgedonicallyHealthy r) || not (receiptIsAlgedonicallyHealthy r)

Reflex-FRP (FRP reativa para UIs)

Use Reflex para UIs reativas que reagem a Recibos Soberanos em tempo real:

-- src/Paebiru/Reflex.hs
{-# LANGUAGE OverloadedStrings #-}

module Paebiru.Reflex where

import Reflex
import Reflex.Dom

import Paebiru.Core
import Paebiru.Events

-- | Widget que mostra Recibos Soberanos em tempo real
receiptWidget :: MonadWidget t m => PaebiruNode -> m ()
receiptWidget node = do
  -- EventTrigger que dispara em cada Recibo
  receipts <- performEventAsync $ fmap withReceipt (meshEventTrigger node)
  el "ul" $ do
    simpleList receipts $ \receipt -> do
      el "li" $ do
        text (receiptCid receipt)
  where
    withReceipt :: MeshEvent -> (Receipt -> IO ()) -> IO ()
    withReceipt (ReceiptProduced r) cb = cb r
    withReceipt _ _ = return ()

    meshEventTrigger :: PaebiruNode -> Event t MeshEvent
    meshEventTrigger node = ...  -- polling ou subscription

Scotty (microframework web estilo Sinatra)

-- src/Paebiru/Scotty.hs
import Web.Scotty
import qualified Data.ByteString.Lazy.Char8 as BL

runMeshScotty :: FilePath -> IO ()
runMeshScotty storage = do
  node <- createNode storage
  startNode node
  scotty 1975 $ do
    get "/healthz" $ text "OK"
    post "/messages" $ do
      body <- body
      (target, payload) <- parseJson body
      receipt <- liftIO $ sendMessage node target payload
      json receipt

distributed-process (Cloud Haskell)

Já mostrado acima. Resumo:

  • Mapeia MeshEvent ↔ mensagens tipadas via SendPort
  • DProcess (distributed process) abstrai location transparency
  • Gera automaticamente serialização de tipos via deriving Typeable
  • Distributed supervision de meshNodeProcess via whereisRemoteAsync

5. Veja também

🍎 Swift (paebiru-swift)

O binding Swift integra o PAEBIRU em iOS, macOS, watchOS, tvOS, visionOS, em servidores Vapor e Hummingbird (Swift server-side), e em SwiftWasm (WebAssembly no navegador). Utiliza o UniFFI da Mozilla (mesmo motor usado pelo Firefox Sync) para gerar bindings Swift idiomáticos sobre o paebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com actor (Swift 5.5+) para concorrência segura, async/await para hot-path, e AsyncStream para eventos.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via actor: instâncias nativas (nó, identidade, recibo) são representadas por tipos final class em Swift, mas expostas como actor PaebiruNode (Swift 5.5+). O actor garante isolamento de memória entre tasks concorrentes — casa naturalmente com o GALS do PAEBIRU.
  • Convenção de nomenclatura:
    • actor, struct, enum, class, protocol em UpperCamelCase (PaebiruNode, MeshEvent).
    • Métodos, propriedades e funções em lowerCamelCase (start(), sendMessage(target:payload:), microJoules).
    • Constantes em lowerCamelCase (não UPPER_SNAKE).
    • Sendable aplicado a todos os tipos que cruzam fronteiras de actor (garantia de thread-safety em compile-time).
  • Gerenciamento de memória: ARC cuida da retenção do handle opaco. deinit chama paebiru_node_destroy automaticamente. Não há close() manual — apenas deixe o actor sair de escopo. Para cleanup imediato, chame await node.shutdown().
  • Distribuição: pacote SwiftPM com Package.swift declarando a dependência binária para libpaebiru. Distribuído via Swift Package Index.
  • Async-first: toda API pública é async (ou async throws). O binding não expõe APIs síncronas (exceto construtores puros).
  • Result ou throws: erros do lado Rust são convertidos para throws Swift (mais idiomático) — enum PaebiruError: Error casa com as variantes do Rust.
  • Structs imutáveis: Receipt, MeshAddress são struct com let em todos os campos — zero mutação após criação. Conforma com Sendable automaticamente.
  • Enums com associated values: MeshEvent é enum com casos peerConnected(PeerId), peerLost(PeerId, reason: String), receiptProduced(Receipt) — pattern matching via switch.
  • Combine para reativos: o binding expõe AsyncStream<MeshEvent> e também um wrapper Publisher<MeshEvent> para integração com SwiftUI / Combine.
  • SwiftUI-ready: o pacote expõe PaebiruNode como @StateObject / @ObservedObject para binding reativo em views.

2. Instalação

Aguardando primeira publicação no Swift Package Index. Quando disponível:

Package.swift (SPM)

// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "MyApp",
    platforms: [
        .iOS(.v16), .macOS(.v13), .watchOS(.v9), .tvOS(.v16),
        .visionOS(.v1)
    ],
    dependencies: [
        .package(url: "https://github.com/paebiru/paebiru-swift.git",
                 from: "0.1.0"),
    ],
    targets: [
        .target(name: "MyApp", dependencies: [
            .product(name: "Paebiru", package: "paebiru-swift"),
        ]),
    ]
)

Xcode

File → Add Packages… → URL https://github.com/paebiru/paebiru-swift.git.

Dependências runtime

  • Swift ≥ 5.9 (para macros de observação SwiftUI, Observable)
  • iOS ≥ 16 / macOS ≥ 13 / watchOS ≥ 9 / tvOS ≥ 16 / visionOS ≥ 1 (para actor, async/await, AsyncStream)
  • Sistema: libpaebiru.dylib (Apple) / libpaebiru.so (Linux server) — distribuída como XCFramework para suportar múltiplas arquiteturas (arm64, x86_64, simulator)

3. Exemplo de Uso

API básica (actor + async/await)

import Paebiru

@main
struct HelloPaebiru {
    static func main() async throws {
        // actor PaebiruNode — todas as chamadas são 'await'
        let node = try await PaebiruNode(storagePath: "~/.paebiru")
        try await node.start()

        // Subscrição via AsyncStream — pattern canônico Swift 5.5+
        let events = await node.meshEvents
        Task {
            for await event in events {
                switch event {
                case .peerConnected(let peerId):
                    print("peer up: \(peerId)")
                case .peerLost(let peerId, let reason):
                    print("peer down: \(peerId) (\(reason))")
                case .receiptProduced(let receipt):
                    print("receipt: \(receipt.cid)")
                }
            }
        }

        // Envia mensagem e recebe Recibo Soberano
        let receipt = try await node.sendMessage(
            target: MeshAddress(string: "12D3KooW...")!,
            payload: "hello".data(using: .utf8)!
        )

        print("Receipt CID : \(receipt.cid)")
        print("Custo µJ     : \(receipt.microJoules)")
        print("Algedonic OK : \(receipt.isAlgedonicallyHealthy)")

        // Cleanup explícito (alternativa: deixe o actor sair de escopo)
        await node.shutdown()
    }
}

Versão SwiftUI (com @StateObject)

import SwiftUI
import Paebiru

@main
struct PaebiruApp: App {
    @StateObject private var mesh = PaebiruMeshViewModel()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(mesh)
                .task {
                    try? await mesh.start()
                }
        }
    }
}

@MainActor
final class PaebiruMeshViewModel: ObservableObject {
    @Published private(set) var receipts: [Receipt] = []
    @Published private(set) var connectedPeers: Set<PeerId> = []

    private let node: PaebiruNode

    init() {
        // Init síncrono só pra alocar; start() é async
        self.node = try! PaebiruNode(storagePath: NSTemporaryDirectory() + "paebiru")
    }

    func start() async throws {
        try await node.start()
        Task {
            for await event in await node.meshEvents {
                await self.handle(event)
            }
        }
    }

    private func handle(_ event: MeshEvent) async {
        switch event {
        case .peerConnected(let peer): connectedPeers.insert(peer)
        case .peerLost(let peer, _):  connectedPeers.remove(peer)
        case .receiptProduced(let r): receipts.append(r)
        }
    }
}

4. Integração com iOS, Vapor e SwiftWasm

iOS / iPadOS (app nativo)

  • Use @StateObject + @MainActor para garantir que mutações de @Published ocorram na main thread.
  • Em SceneDelegate ou App, não chame start() no init (sync) — chame no .task da view para usar async/await corretamente.
  • Para background fetch, configure BGAppRefreshTask no Info.plist e processe eventos recebidos durante o background.
  • Para Push Notifications (notificar recibo crítico), integre via UNUserNotificationCenter no callback de receiptProduced.
  • Permissões necessárias em Info.plist:
    • NSLocalNetworkUsageDescription (mDNS discovery)
    • NSBonjourServices (anunciar serviço _paebiru._tcp)

macOS (app nativa + menu bar)

  • Use MenuBarExtra (macOS 13+) para ícone de status permanente.
  • Combine com Combine para reagir a eventos de malha em views SwiftUI:
    node.meshEventsPublisher
        .receive(on: DispatchQueue.main)
        .sink { event in /* update UI */ }
        .store(in: &cancellables)
    

Vapor (servidor Swift)

  • Configure o nó como singleton no Application:
    // configure.swift
    app.paebiruNode = try await PaebiruNode(storagePath: app.directory.paebiru)
    try await app.paebiruNode.start()
    app.lifecycle.use(...)
    
  • Crie um Controller que expõe endpoints REST consumindo o nó:
    struct PaebiruController: RouteCollection {
        func boot(routes: RoutesBuilder) throws {
            routes.post("messages", use: send)
        }
        func send(req: Request) async throws -> Response {
            let body = try req.content.decode(SendBody.self)
            let receipt = try await req.application.paebiruNode.sendMessage(
                target: body.target, payload: body.payload)
            return .created(json: receipt)
        }
    }
    
  • Em app.shutdown, o nó é desalocado automaticamente via ARC; deinit chama paebiru_node_destroy.

SwiftWasm (rodando no navegador)

  • Compile o binding com SwiftWasm 5.9 toolchain.
  • Use AsyncStream para consumir eventos da malha diretamente em JavaScript via JSExport.
  • Limite de memória do WASM (~4 GB) impõe batching de mensagens > 10/s.

5. Veja também

💎 Ruby (paebiru-ruby)

O binding Ruby integra o PAEBIRU em Rails (web), Sidekiq (background jobs), Hanami (framework leve), Sinatra (microframework), Jekyll (sites estáticos), e em scripts CLI e gems. Utiliza a crate Rust Magnus para expor classes Ruby idiomáticas sobre o paebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com handles opacos encapsulados em classes Ruby, blocos para callbacks, e Fiber (3.0+) para async cooperativo.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via classes Ruby: instâncias nativas (nó, identidade, recibo) são representadas por instâncias de classes Ruby (Paebiru::Node, Paebiru::Identity, Paebiru::Receipt) que encapsulam o VALUE (ponteiro opaco) do paebiru-c. A classe mantém o handle em uma instância @handle e expõe métodos de domínio.
  • Convenção de nomenclatura:
    • frozen_string_literal: true em todos os arquivos (economia de memória, idiomático Ruby 3+).
    • Classes e módulos em PascalCase (Paebiru::Node).
    • Métodos em snake_case (#start, #send_message, #on_message_received).
    • Constantes em UPPER_SNAKE_CASE (Paebiru::VERSION, Paebiru::DEFAULT_PORT).
    • Símbolos para chaves de hash e status (:connected, :disconnected); strings apenas para dados externos.
  • Gerenciamento de memória: o destrutor Ruby def self.finalize é registrado no GC; chama paebiru_node_destroy quando o objeto é coletado. Para cleanup explícito, #close é fornecido (libera imediatamente, sem esperar GC).
  • Distribuição: gem paebiru no RubyGems com bundle add paebiru para Rails.
  • Blocks para callbacks: eventos de malha são consumidos via node.on_message_received { |event| ... } — o block é a abstração canônica Ruby para callbacks (mais natural que Proc.new ou lambda explícito).
  • Fiber para async (Ruby 3.0+): o binding expõe eventos via Fiber.yield e Fiber#resume — casa com a metáfora de eventos do Kernel GALS. Combinado com Fiber Scheduler (interface de async/await) do Ruby 3.0+.
  • Ractor para paralelismo (Ruby 3.0+): cargas pesadas (verificação ZK, deserialização Prolly Tree) podem rodar em Ractors separados (similar a isolates Dart).
  • Pattern matching (Ruby 3.0+): o binding expõe eventos como Data (value object imutável, Ruby 3.2+) que pode ser consumido via case ... in.
  • YJIT-friendly: o código é compatível com YJIT (JIT do Ruby 3.0+); evita reflection em hot-path, evita method_missing.

2. Instalação

Aguardando primeira publicação no RubyGems. Quando disponível:

Gemfile (Rails, Bundler)

gem 'paebiru', '~> 0.1'
bundle install

Standalone

gem install paebiru

Dependências runtime

  • Ruby ≥ 3.0.0 (para Fiber Scheduler, pattern matching, Ractor)
  • Sistema: libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows) instalada via pacote de sistema ou bundle na própria gem (herdado por extensions: em extconf.rb ou prebuilt via paebiru Rust crate embutida).

3. Exemplo de Uso

API básica (bloco para callback + ensure para cleanup)

# frozen_string_literal: true

require 'paebiru'

node = Paebiru::Node.new('~/.paebiru')
begin
  node.start

  # Subscrição a eventos via block (mais idiomático que lambda)
  node.on_message_received do |event|
    warn "msg de #{event.peer_id}: #{event.payload.bytesize} bytes"
  end

  # Envia mensagem e recebe Recibo Soberano
  receipt = node.send_message(
    target:  '12D3KooW...',
    payload: 'hello'
  )

  puts "Receipt CID : #{receipt.cid}"
  puts "Custo µJ     : #{receipt.micro_joules}"
  puts "Algedonic OK : #{receipt.algedonically_healthy?}"
ensure
  node.close  # cleanup explícito (finalizer também chamaria, no GC)
end

Versão com pattern matching (Ruby 3.0+)

node.on_mesh_event do |event|
  case event
  in Paebiru::PeerConnected(peer_id:)
    puts "peer up: #{peer_id}"
  in Paebiru::PeerLost(peer_id:, reason:)
    puts "peer down: #{peer_id} (#{reason})"
  in Paebiru::ReceiptProduced(receipt:)
    puts "receipt: #{receipt.cid}"
  end
end

Versão com Fiber (Ruby 3.0+ Fiber Scheduler)

require 'async'  # gem async
require 'paebiru'

Async do
  node = Paebiru::Node.new('~/.paebiru')
  node.start

  # Aguarda próximo evento como se fosse uma chamada de I/O
  event = node.await_next_mesh_event
  puts "evento: #{event.class}"
ensure
  node&.close
end

4. Integração com Rails, Sidekiq e Hanami

Ruby on Rails (full-stack)

  • Crie um initializer (config/initializers/paebiru.rb):
    # frozen_string_literal: true
    
    Rails.application.config.paebiru_node = Paebiru::Node.new(
      Rails.root.join('storage/paebiru').to_s
    )
    Rails.application.config.paebiru_node.start
    
    # Garante cleanup no shutdown do Puma
    at_exit { Rails.application.config.paebiru_node&.close }
    
  • Acesse o nó em controllers/services via Rails.configuration.paebiru_node.
  • Para emitir um Recibo Soberano a cada request, crie um rack middleware (app/middleware/paebiru_receipt.rb):
    class PaebiruReceipt
      def initialize(app, node:)
        @app = app
        @node = node
      end
    
      def call(env)
        status, headers, body = @app.call(env)
        @node.send_message(
          target: 'audit_peer',
          payload: { request_id: env['action_dispatch.request_id'] }
        )
        [status, headers, body]
      end
    end
    

Sidekiq (background jobs)

  • Em jobs que requerem prova de execução:
    class FederatedTrainingJob
      include Sidekiq::Job
      sidekiq_options retry: 3, queue: :federated
    
      def perform(model_id, dataset_cid)
        node = Paebiru::Node.instance  # singleton global
        delta = compute_local_delta(model_id, dataset_cid)
        receipt = node.send_message(
          target: 'coordinator',
          payload: delta,
          plasmid: 'fedavg.gradient.v1'
        )
        Sidekiq.logger.info("delta enviado: #{receipt.cid}")
      end
    end
    
  • Não chame #close no final do job — o nó é singleton e outros jobs podem usá-lo. Cleanup é responsabilidade do initializer.

Hanami (framework leve)

  • Configure o nó em config/app.rb:
    # frozen_string_literal: true
    
    module MyApp
      class App < Hanami::App
        config.paebiru = Paebiru::Node.new('storage/paebiru')
        config.paebiru.start
      end
    end
    
  • Use providers (app/providers/paebiru.rb) para injetar o nó em componentes.

Jekyll (sites estáticos)

  • Em plugins customizados (_plugins/paebiru_tag.rb), use o nó para gerar Recibos Soberanos a cada build do site:
    module Jekyll
      class PaebiruTag < Liquid::Tag
        def render(context)
          node = context.registers[:site].config['paebiru_node']
          node.send_message(target: 'build_audit', payload: @text)
          @text
        end
      end
    end
    Liquid::Template.register_tag('paebiru_audit', Jekyll::PaebiruTag)
    

5. Veja também

🐘 PHP (paebiru-php)

O binding PHP integra o PAEBIRU em servidores web (PHP-FPM, Apache mod_php), em frameworks MVC (Laravel, Symfony, CodeIgniter), em runtimes assíncronos (Swoole, OpenSwoole, AMPHP, ReactPHP), e em plugins WordPress/Drupal/Magento que precisam emitir Recibos Soberanos por requisição. Utiliza a crate Rust ext-php-rs para expor uma extensão Zend nativa, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com handles opacos e readonly class (PHP 8.2+) para tipos imutáveis.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via int: instâncias nativas (nó, identidade, recibo) são representadas por um int de 64 bits (Zend zend_long) que encapsula o ponteiro opaco. A classe Paebiru\Sdk\Node guarda esse handle em propriedade private readonly int $handle e nunca o expõe fora da extensão.
  • Convenção de nomenclatura: namespace raiz Paebiru\Sdk; classes em PascalCase (PSR-12), métodos em camelCase, constantes em UPPER_SNAKE_CASE (compat PHP 8.1 enum).
  • Gerenciamento de memória: classes que carregam handle implementam __destruct (legado) e limpeza via try/finally (recomendado). Em Swoole/AMPHP, registre register_shutdown_function para cleanup em caso de fatal.
  • Distribuição: pacote Composer paebiru/paebiru-php + extensão .so/.dll instalada via PECL ou pré-compilada no php.ini.
  • Tipagem forte: a API pública é totalmente tipada (PHP 8.2+) — readonly class, enum, intersection types, never return type. Sem mixed em hot-path.
  • Zero-cópia: payloads de mensagem trafegam como string PHP (que é char* no Zend) ou SplFixedArray de inteiros para hot-path binário. Nunca json_encode em hot-path.
  • Fibers para async (PHP 8.1+): o binding expõe eventos via Fiber — suspende a fiber, retoma quando o evento chega. Casa naturalmente com a metáfora de eventos do Kernel GALS.

2. Instalação

Aguardando primeira publicação. Quando disponível:

Via Composer (código PHP)

composer require paebiru/paebiru-php

Via PECL (extensão nativa)

pecl install paebiru

E habilite no php.ini:

extension=paebiru.so
[paebiru]
paebiru.libpath = "/usr/local/lib/libpaebiru.so"
paebiru.default_storage = "/var/lib/paebiru"

Verificação

php -m | grep paebiru
php -r "echo phpversion('paebiru'), PHP_EOL;"

3. Exemplo de Uso

API básica (try/finally para cleanup)

<?php
declare(strict_types=1);

use Paebiru\Sdk\Node;
use Paebiru\Sdk\Receipt;

$node = new Node('/var/lib/paebiru');
try {
    $node->start();

    // Subscrição a eventos via closure
    $node->onMessageReceived(function (MeshEvent $event): void {
        // $event->payload é string (zero-cópia sobre buffer nativo)
        fprintf(STDERR, "msg de %s: %d bytes\n",
                $event->peerId, strlen($event->payload));
    });

    // Envia mensagem e recebe Recibo Soberano
    $receipt = $node->sendMessage(
        target: '12D3KooW...',
        payload: 'hello',
    );

    printf("Receipt CID : %s\n", $receipt->cid);
    printf("Custo µJ     : %d\n", $receipt->microJoules);
    printf("Algedonic OK : %s\n",
           $receipt->isAlgedonicallyHealthy ? 'true' : 'false');
} finally {
    $node->close();
}

Versão com match (PHP 8.0+) e enum

use Paebiru\Sdk\MeshEvent;

$handler = function (MeshEvent $event): void => match (true) {
    $event instanceof PeerConnected => fprintf(STDERR, "peer up: %s\n", $event->peerId),
    $event instanceof PeerLost      => fprintf(STDERR, "peer down: %s (%s)\n",
                                                $event->peerId, $event->reason->name),
    $event instanceof ReceiptProduced => printf("receipt: %s\n", $event->receipt->cid),
};

Versão com Fiber (PHP 8.1+)

$fiber = new Fiber(function (): void {
    while (true) {
        $event = Fiber::suspend();  // bloqueia até próximo evento
        // processa $event
    }
});
$fiber->start();

$node->onMessageReceived(fn($e) => $fiber->resume($e));

4. Integração com Swoole, WordPress e Laravel

Swoole / OpenSwoole (servidor assíncrono)

  • Em Coroutine (Swoole), o handle nativo é thread-local — cada worker tem seu próprio Node, não compartilhe entre coroutines sem chan ou Atomic para serializar.
  • Use Swoole\Coroutine\Channel para passar eventos entre coroutines que escutam a mesma malha PAEBIRU.
  • Configure swoole.use_shortname = 'Off' para evitar conflito com Fiber.

WordPress (plugin emitindo Recibos Soberanos)

  • Crie o Node em plugins_loaded (hook); guarde em variável global $GLOBALS['paebiru_node'].
  • Em wp_ajax_* e wp_rest_*, chame $node->sendMessage(...) com o autor da ação e o conteúdo validado por CDDL.
  • Em register_deactivation_hook, chame $node->close() — sem isso, o handle vaza até o WordPress matar o processo.
  • Cuidado com shortcodes: shortcodes renderizam em the_content filter; enviar Recibos Soberanos nesse ponto causa flood de receipts. Faça em wp_loaded ou template_redirect.

Laravel (framework full-stack)

  • Crie um ServiceProvider que inicializa o Node como singleton no container:
    $this->app->singleton(Node::class, fn() => new Node(
        config('paebiru.storage_path')
    ));
    
  • Exponha configuração em config/paebiru.php lendo do .env:
    return [
        'storage_path' => env('PAEBIRU_STORAGE_PATH', storage_path('paebiru')),
        'api_port'     => (int) env('PAEBIRU_API_PORT', 1975),
    ];
    
  • Em App\Console\Commands, crie comandos artisan (paebiru:start, paebiru:status, paebiru:submit) que delegam ao Node.

Symfony (framework components)

  • Bundles podem ser criados (paebiru/symfony-bundle planejado) expondo o Node como serviço com autowire por type-hint.
  • Use o Messenger component para enfileirar Recibos Soberanos como mensagens assíncronas processadas em workers separados.

5. Veja também

🌙 Lua (paebiru-lua)

O binding Lua integra o PAEBIRU em scripts embarcados, motores de jogo (LÖVE, Defold, Corona/Solar2D, Roblox via Luau), e em servidores LuaJIT de alta performance (OpenResty, Redis modules, Neovim plugins). Utiliza a crate Rust mlua para fazer a ponte entre o paebiru-c e o estado Lua, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com userdata opaco e metatables para a API OO.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via userdata: instâncias nativas (nó, identidade, recibo) são representadas por userdata Lua contendo um *mut c_void. Acessos passam por uma metatable com __index, __newindex, __gc (finalizer que chama paebiru_node_destroy).
  • Convenção de nomenclatura: módulo raiz paebiru (minúsculo); tipos exportados em PascalCase global (paebiru.PaeNode, paebiru.PaeReceipt); métodos em lowerCamelCase (paeNode:start()).
  • Gerenciamento de memória: a __gc metamethod garante paebiru_node_destroy quando o userdata é coletado. Recomenda-se pcall(close, node) explícito para cleanup imediato (finalizer pode atrasar).
  • Módulo: paebiru (rock público).
  • Sem classes, sem tipos estáticos: a API é dinâmica; erros de tipo são detectados em runtime via pcall + checagem de type(v) == "userdata".
  • Coroutines para async: o binding expõe eventos como coroutines nativas do Lua (coroutine.yield, coroutine.resume) — o modelo casa naturalmente com a metáfora de eventos do Kernel GALS. LuaJIT é fortemente recomendado para hot-path de produção.
  • LuaJIT-first quando disponível: o rock detecta em tempo de carga se LuaJIT está presente; em LuaJIT usa ffi.cdef para chamadas zero-overhead ao paebiru-c, em Lua 5.x cai para a API C via mlua.

2. Instalação

Aguardando primeira publicação. Quando disponível:

LuaRocks (recomendado)

luarocks install paebiru

LuaRocks — versão de desenvolvimento

luarocks install --dev-dir paebiru

OpenResty (servidor HTTP LuaJIT)

# nginx.conf
http {
    init_by_lua_block {
        local paebiru = require("paebiru")
        local node, err = paebiru.node_create("/var/lib/paebiru")
        if not node then error(err) end
        node:start()
    }
}

LÖVE2D (motor de jogo 2D)

-- love.conf.lua
love.conf = function(t)
    t.modules.paebiru = { require = "paebiru" }
end

3. Exemplo de Uso

API básica (pcall + cleanup explícito)

local paebiru = require("paebiru")

local node, err = paebiru.node_create("./storage")
if not node then
    error("falha ao criar nó: " .. tostring(err))
end

local ok, err = pcall(function()
    node:start()

    -- Subscrição a eventos via coroutine
    local co = coroutine.create(function()
        while true do
            local event = coroutine.yield()  -- bloqueia até próximo evento
            if event.type == "message" then
                print(("msg de %s: %d bytes"):format(
                    event.peer_id, #event.payload))
            elseif event.type == "peer_lost" then
                print("peer down: " .. event.peer_id)
            end
        end
    end)
    coroutine.resume(co)  -- prime a coroutine

    node:on_message(function(event)
        coroutine.resume(co, event)
    end)

    -- Envia mensagem e recebe Recibo Soberano
    local receipt, send_err = node:send_message({
        target = "12D3KooW...",
        payload = "hello",
    })
    if not receipt then
        error("falha no envio: " .. tostring(send_err))
    end

    print("Receipt CID : " .. receipt.cid)
    print("Custo µJ     : " .. receipt.micro_joules)
    print("Algedonic OK : " .. tostring(receipt.is_algedonically_healthy))
end)

-- Cleanup explícito (finalizer também faria, mas só quando GC rodar)
node:close()

if not ok then error(err) end

Versão com xpcall (captura stack trace)

local ok, err = xpcall(function()
    node:start()
    -- ... lógica ...
end, debug.traceback)

if not ok then
    io.stderr:write("PAEBIRU error:\n" .. tostring(err) .. "\n")
    node:close()
    os.exit(1)
end

4. Integração com LÖVE, Defold e OpenResty

LÖVE2D (jogos 2D, simulações, gêmeos digitais)

  • Em love.load, chame node:start() e armazene o handle em variável global; não recrie o nó em love.update (causa leak do userdata).
  • Em love.draw, use coroutine.status(co) para renderizar apenas quando há eventos pendentes.
  • Em love.quit, chame node:close() antes de sair — sem isso, o finalizer roda e fecha o nó, mas warnings de graceful shutdown aparecem nos logs.

Defold (jogos mobile-first, hot-reload)

  • Use o módulo paebiru.defold que expõe uma API OO com init, final, on_message, on_input.
  • Hot-reload do editor: o binding desregistra callbacks no final para não acumular inscrições zumbis.

OpenResty (servidor HTTP de alta performance)

  • Use init_by_lua_block (uma vez por worker master) para criar o nó; não em init_worker_by_lua_block (roda por worker, multiplica handles).
  • Em content_by_lua_block, exponha endpoints que consultam node:status() ou injetam plasmídeos via node:submit_plasmid.
  • Em log_by_lua_block, emita Recibos Soberanos de auditoria para cada requisição HTTP.

Redis (módulo nativo em C, chama Lua)

  • Configure lua-time-limit alto (≥ 5000ms) — scripts PAEBIRU podem demorar para validar provas ZK.
  • Use redis.call('PAE_STATUS') (registrado pelo binding) para consultar saúde do nó de dentro do script.

5. Veja também

📊 R (paebiru-r)

O binding R integra o PAEBIRU em pipelines de ciência de dados, estatística, bioinformática (Bioconductor), epidemiologia e aprendizado federado. Utiliza a crate Rust extendr para gerar bindings R idiomáticos sobre o paebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com R6::R6Class (POO moderna em R), tryCatch para erros, e ponte direta para data.table / arrow / torch via ALTREP quando aplicável.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via externalptr: instâncias nativas (nó, identidade, recibo) são representadas por externalptr — o tipo canônico do R para ponteiros opacos vindos de C/Rust. A classe R6::R6Class PaebiruNode$new() envolve o externalptr e expõe métodos $start(), $send_message(), etc. O finalizer (finalize = TRUE no R6) chama paebiru_node_destroy quando o objeto é coletado pelo GC.
  • Convenção de nomenclatura: pacote raiz paebiru (em R é minúsculo e sem _); classes R6 em PaebiruNode (PascalCase, expostas como paebiru::Node); métodos em snake_case ($send_message(), $on_message_received()) para casar com o estilo tidyverse.
  • Gerenciamento de memória: R6 com finalize = TRUE chama o destrutor automaticamente no GC. Para cleanup explícito, $close() é fornecido (libera imediatamente, sem esperar GC).
  • Distribuição: pacote CRAN paebiru com Bioconductor como alvo secundário (depois de aceitação CRAN).
  • Tipagem dinâmica: R não tem tipos estáticos. A API usa stopifnot() para validar precondições e tryCatch() para capturar erros. Vetores são usados em vez de coleções tipadas.
  • Zero-cópia:
    • raw (vetor de bytes brutos) e numeric são recebidos via ALTREP quando o lado Rust expõe AltRep — evita cópia de buffers grandes.
    • Para DataFrames grandes, integre com arrow (Apache Arrow) via paebiru_node$query() que retorna um Table Arrow sem cópia.
  • Programação funcional: callbacks de eventos são funções (closures R), passadas como function(event) { ... }. Casa com a cultura funcional do R.
  • Pipe nativo: usa o pipe |> (R 4.1+) para encadear operações idiomáticas.

2. Instalação

Aguardando primeira publicação no CRAN. Quando disponível:

CRAN (recomendado)

install.packages("paebiru")

Desenvolvimento (GitHub)

# install.packages("remotes")
remotes::install_github("paebiru/paebiru-r")

Bioconductor (release subsequente)

if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
BiocManager::install("paebiru")

Dependências runtime

  • R ≥ 4.2.0 (para ALTREP maduro e pipe |>)
  • Sistema: libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows) instalada via pacote de sistema ou bundle no próprio pacote R

3. Exemplo de Uso

API básica (R6 + tryCatch + pipe nativo)

library(paebiru)

# Cria nó — handle é externalptr encapsulado em R6
node <- PaebiruNode$new(storage_path = "~/.paebiru")

# Cleanup explícito (finalizer também chamaria, mas só no GC)
on.exit(node$close(), add = TRUE)

tryCatch({
  node$start()

  # Subscrição a eventos via closure
  node$on_message_received(function(event) {
    message(sprintf("msg de %s: %d bytes", event$peer_id, length(event$payload)))
  })

  # Envia mensagem e recebe Recibo Soberano
  receipt <- node$send_message(
    target = "12D3KooW...",
    payload = charToRaw("hello")  # vetor raw
  )

  cat(sprintf("Receipt CID : %s\n", receipt$cid))
  cat(sprintf("Custo µJ     : %d\n", receipt$micro_joules))
  cat(sprintf("Algedonic OK : %s\n", receipt$is_algedonically_healthy))
}, error = function(e) {
  # AlgedonicSensor exposto via condições R
  message(sprintf("PAEBIRU error: %s", conditionMessage(e)))
})

Versão pipe (|>) com tidyverse

library(paebiru)
library(dplyr)

node <- PaebiruNode$new("~/.paebiru")
on.exit(node$close())

node |>
  start_node() |>  # wrapper que chama $start() e loga status
  subscribe_events(function(event) {
    event$payload |>
      rawToChar() |>
      message()
  }) |>
  send_message("12D3KooW...", charToRaw("hello"))

4. Integração com Aprendizado Federado e Bioinformática

Aprendizado Federado (paebiru-learn via R)

R é a linguagem canônica para ciência de dados federada em domínios onde a privacidade é lei (saúde, finanças, epidemiologia). O binding expõe wrappers idiomáticos:

library(paebiru)
library(torch)  # ou keras

# Computa weight delta localmente (em R) e envia como CausalBlock
local_model |>
  compute_weight_delta(global_model) |>
  paebiru_submit(
    target = "coordinator_peer",
    plasmid = "fedavg.gradient.v1"
  ) |>
  wait_for_aggregation() |>
  update_model()

Para federação bizantina (redes > 50 nós), use o argumento aggregation = "krum" ou "foolsgold" que delega ao BC Aprendizado:

paebiru_submit(
  delta = local_delta,
  plasmid = "fedavg.gradient.v1",
  aggregation = "krum"
)

Bioinformática (Bioconductor)

Pacote Bioconductor (planejado, pós-CRAN) integra com classes canônicas do Bioconductor:

library(paebiru)
library(SummarizedExperiment)  # classe central Bioconductor

# SummarizedExperiment → CausalBlock via compute-over-data
se <- SummarizedExperiment(...)
node$compute_over_data(
  plasmid = "deseq2.differential_expression.v2",
  data_cid = se_cid,
  callback = function(result_cid) {
    # Resultado fica no Oceano;Receipt Soberano chega via $on_receipt()
    message("Resultado disponível: ", result_cid)
  }
)

Epidemiologia e ciência aberta

  • Combine com o pacote outbreaks (conjuntos de dados de surtos) para gerar Recibos Soberanos de cada inferência estatística — auditabilidade científica ponto-a-ponto.
  • Use plumber para expor o nó PAEBIRU como API REST; o binding expõe node$as_plumber_preroute() para integração automática.

5. Veja também

🟪 Julia (Paebiru.jl)

O binding Julia é, junto com Zig, um dos dois únicos que consomem paebiru-c diretamente via FFI C (sem crate Rust intermediária) — mas com uma twist: Julia adiciona múltiplos despachos (multiple dispatch) e metaprogramação via macros, que permitem um estilo de binding quase zero-cost e extensível. Além disso, Julia é a linguagem canônica para o subconjunto científico do PAEBIRU: FedAvg (via Flux.jl / Lux.jl), Langevin dynamics (via DifferentialEquations.jl), ZK number theory (via Nemo.jl), estatística da malha (via DataFrames.jl), e GPU acceleration (via CUDA.jl / AMDGPU.jl / Metal.jl / oneAPI.jl).

O binding usa @ccall (macro moderna, type-safe, sobre ccall) para chamar libpaebiru, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com mutable struct para ownership do handle C, Channel para eventos assíncronos, e Base.Ref / unsafe_wrap para zero-copy via Ptr{T}.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via mutable struct + Ref: instâncias nativas (nó, identidade, recibo) são representadas em Julia por mutable struct PaebiruNode handle::Ptr{Cvoid} end (ou Ref{Ptr{Cvoid}} para semântica de ownership explícita). O handle C nunca é exposto fora das funções de binding — usuários sempre passam a struct opaca.
  • Convenção de nomenclatura:
    • Módulos, tipos, structs em PascalCase (Paebiru, Paebiru.Node, Paebiru.Receipt, Paebiru.MeshEvent).
    • Funções, variáveis, campos em snake_case (start, send_message, micro_joules).
    • Constantes em UPPER_SNAKE_CASE (PAEBIRU_DEFAULT_PORT).
    • Sem classes — usa struct + funções com múltiplos despachos (send_message(::Node, ::AbstractString, ...), send_message(::Node, ::Vector{UInt8}, ...)).
    • 1-based indexing (convenção Julia, igual a R, Lua, MATLAB).
    • Símbolos para tags: :peer_connected, :peer_lost, :receipt_produced (símbolos Julia são interned strings).
  • Gerenciamento de memória: Base.close(node::Paebiru.Node) chama paebiru_node_destroy via @ccall. Use try / finally para garantir cleanup, ou use o Block package (Julia ≥ 1.9) com close em escopo léxico.
  • Distribuição: pacote Julia Paebiru (registrado como Paebiru.jl no JuliaGeneral). Importação via using Paebiru.
  • Múltiplos despachos como superpoder: diferentes tipos de payload (AbstractString, Vector{UInt8}, SubArray{UInt8}) → cada um gera uma especialização LLVM diferente → zero overhead de boxing em hot-path.
  • Macros para sugar sintático: @paebiru_init, @receipt, @mesh_event_handler — em vez de configurar manualmente, o usuário decora seu código com macros que geram o boilerplate.
  • Channel para eventos assíncronos: Channel{MeshEvent}(sz) é o canônico Julia para stream de eventos entre tasks (similar a Stream<T> Dart, AsyncStream<T> Swift).
  • Zero-cópia via Ptr{T} + unsafe_wrap: arrays Julia podem ser passados diretamente como Ptr{UInt8} para o lado C sem cópia, usando Base.unsafe_wrap para criar um Vector{UInt8} view sobre memória C.
  • Type stability: funções hot-path são anotadas com tipos concretos (::Int64, ::Ptr{Cvoid}) para garantir que o compilador LLVM gere código C-like.
  • GPU-ready: o binding expõe arrays CUDA (CuArray{UInt8}) que podem ser passados ao lado C via ponteiro de device (CUDA.jl resolve o Ptr{UInt8} automaticamente para device pointer).

2. Instalação

Aguardando primeiro registro no JuliaGeneral. Quando disponível:

Via Pkg (REPL)

julia> ]
pkg> add Paebiru

Via Project.toml

[deps]
Paebiru = "..."  # UUID atribuído pelo JuliaGeneral

Verificação

julia> using Paebiru
julia> Paebiru.version()
v"0.1.0"

Dependências runtime

  • Julia ≥ 1.10 (para Base.@ccall, melhorias em unsafe_wrap, pattern matching, @debug estruturado)
  • Sistema: libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows) — instalável via julia> using Pkg; Pkg.add("Paebiru_jll") (binário pré-compilado por Yggdrasil / JuliaPackaging)

3. Exemplo de Uso

API básica (multiple dispatch + Channel + @ccall)

# src/mesh.jl
module Mesh

using Paebiru
using Dates

# --- múltiplos despachos para send_message ---

"""
    send_message(node::Node, target::AbstractString, payload::AbstractString) :: Receipt

Envia mensagem com payload string (convertido internamente para
Vector{UInt8}). Despacho separado para Vector{UInt8} evita
conversão quando o caller já tem bytes brutos.
"""
function send_message(node::Node, target::AbstractString,
                      payload::AbstractString)::Receipt
    bytes = codeunits(payload)  # zero-copy para UTF-8
    return send_message(node, target, bytes)
end

function send_message(node::Node, target::AbstractString,
                      payload::AbstractVector{UInt8})::Receipt
    return _send_message_unsafe(node, target, payload)
end

# O wrapper interno usa @ccall (macro type-safe) sobre ccall
function _send_message_unsafe(node::Node, target::AbstractString,
                               payload::AbstractVector{UInt8})::Receipt
    receipt_buf = Ref{ReceiptBuffer}(ReceiptBuffer())
    rc = @ccall libpaebiru.paebiru_node_send_message(
        node.handle::Ptr{Cvoid},
        target::Cstring,
        pointer(payload)::Ptr{UInt8},
        length(payload)::Csize_t,
        receipt_buf::Ref{ReceiptBuffer}
    )::Cint
    rc == 0 || error("paebiru_node_send_message failed: rc=$rc")
    return _make_receipt(receipt_buf[])
end

# --- Channel para eventos assíncronos ---

"""
    mesh_events(node::Node) :: Channel{MeshEvent}

Retorna um Channel que emite eventos da malha conforme ocorrem.
Use `take!` para consumir, `close` para parar.
"""
function mesh_events(node::Node; bufsize::Int=64)::Channel{MeshEvent}
    chan = Channel{MeshEvent}(bufsize)
    @async begin
        try
            while isopen(chan)
                event = _poll_event(node)
                if event !== nothing
                    put!(chan, event)
                end
                sleep(0.001)  # 1 ms poll
            end
        finally
            close(chan)
        end
    end
    return chan
end

end # module

Versão com macro @mesh_event_handler

@mesh_event_handler function handle(event::MeshEvent)
    if event.type === :peer_connected
        @info "peer up" peer_id=event.peer_id
    elseif event.type === :peer_lost
        @warn "peer down" peer_id=event.peer_id reason=event.reason
    elseif event.type === :receipt_produced
        @info "receipt" cid=event.receipt.cid
    end
end

A macro @mesh_event_handler descompila em if/elseif/else type-stable, com logging estruturado do Logging.jl (nativo Julia).

Versão com try / finally (cleanup garantido)

function main()
    node = Paebiru.Node("./storage")  # constructor chama @ccall
    try
        Paebiru.start(node)

        for event in mesh_events(node)
            handle(event)  # definida acima
        end
    finally
        close(node)  # chama paebiru_node_destroy
    end
end

main()

4. Integração com FedAvg, Langevin e Ising

Aprendizado Federado (via Flux.jl / Lux.jl)

Julia é a linguagem canônica para ML/AI de alta performance junto com Python. O binding integra diretamente com Flux.jl:

using Flux
using Paebiru

# Modelo local (Chain do Flux)
model = Chain(
    Dense(784 => 128, relu),
    Dense(128 => 64, relu),
    Dense(64 => 10),
)
ps, st = Flux.setup(model, rand(Float32, 784))

# Computa weight delta local
function compute_delta(ps, local_data)
    grads = Flux.gradient(ps) do
        loss = Flux.crossentropy(model(local_data.x), local_data.y)
        return loss
    end
    return grads  # NamedTuple de gradientes
end

# Envia delta como CausalBlock via PAEBIRU
node = Paebiru.Node("./storage")
try
    delta = compute_delta(ps, my_data)
    receipt = send_message(node, "coordinator", serialize(delta))
    @info "delta enviado" cid=receipt.cid µj=receipt.micro_joules
finally
    close(node)
end

Para federação bizantina em redes > 50 nós, use o argumento aggregation=:krum ou aggregation=:foolsgold:

receipt = send_message(node, "coordinator", serialize(delta);
                       aggregation=:krum, plasmid="fedavg.gradient.v1")

Langevin Dynamics (via DifferentialEquations.jl)

O scheduler Langevin do PAEBIRU é descrito por equações de Langevin estocásticas. Julia tem o melhor solver para isso:

using DifferentialEquations
using StochasticDiffEq

# Langevin equation: dX = -∇U(X) dt + σ dW_t
function langevin!(du, u, p, t)
    # Gradiente do potencial U (ex: poço duplo)
    du[1] = -4.0 * u[1]^3 + 4.0 * u[1]
    du[2] = -4.0 * u[2]^3 + 4.0 * u[2]
end

function langevin_noise!(du, u, p, t)
    du[1] = 1.0  # σ
    du[2] = 1.0
end

# Solver SDE
tspan = (0.0, 10.0)
u0 = [1.0, -1.0]
prob = SDEProblem(langevin!, langevin_noise!, u0, tspan)
sol = solve(prob, SOSRI())  # Stochastic ODE solver

# Envia trajetórias para a malha como CausalBlock
node = Paebiru.Node("./storage")
try
    for traj in sol.u[1:100:end]  # amostra a cada ~100 timesteps
        receipt = send_message(node, "scheduler", serialize(traj);
                               plasmid="langevin.trajectory.v1")
    end
finally
    close(node)
end

Ising Solver (BC Math)

O Hamiltoniano de Ising do BC Math (descrito em mathematics.md) pode ser resolvido em Julia via JuMP.jl ou simulated annealing:

using JuMP, Optim

# Hamiltoniano: H = -J Σ s_i s_j - h Σ s_i
function ising_energy(s::Vector{Int}, J::Float64, h::Float64)
    n = length(s)
    energy = 0.0
    for i in 1:n-1
        energy -= J * s[i] * s[i+1]  # acoplamento ferromagnético
    end
    energy -= h * sum(s)
    return energy
end

# Simulated annealing
function anneal(n::Int, J::Float64, h::Float64, T_max=10.0, T_min=0.01, n_steps=10000)
    s = rand([-1, 1], n)
    T = T_max
    for step in 1:n_steps
        T = T_max * (T_min / T_max)^(step / n_steps)
        i = rand(1:n)
        s_new = copy(s); s_new[i] *= -1
        ΔE = ising_energy(s_new, J, h) - ising_energy(s, J, h)
        if ΔE < 0 || rand() < exp(-ΔE / T)
            s = s_new
        end
    end
    return s
end

# Resultado → mesh como CausalBlock
node = Paebiru.Node("./storage")
try
    s = anneal(100, 1.0, 0.0)  # 100 spins, J=1, h=0
    receipt = send_message(node, "scheduler", serialize(s);
                           plasmid="ising.solution.v1")
    @info "Ising solved" cid=receipt.cid energy=ising_energy(s, 1.0, 0.0)
finally
    close(node)
end

GPU Acceleration (via CUDA.jl / AMDGPU.jl / Metal.jl)

Arrays Julia já são passíveis de GPU via GPUArrays.jl. O binding aceita CuArray{UInt8} (CUDA) / ROCArray{UInt8} (AMD) / MtlArray{UInt8} (Apple Metal) e o ccall resolve o ponteiro correto (host vs device) automaticamente:

using CUDA
using Paebiru

# Payload na GPU — zero cópia entre GPU↔host
payload_gpu = CUDA.fill(0x42, 1024)  # CuArray{UInt8}

node = Paebiru.Node("./storage")
try
    # A macro @ccall resolve pointer(payload_gpu) para device pointer
    receipt = send_message(node, "target", payload_gpu; plasmid="gpu.payload.v1")
    @info "enviado da GPU" cid=receipt.cid
finally
    close(node)
end

Por que isso é poderoso: em FedAvg com modelos grandes (> 1 GB de parâmetros), o delta gradient fica inteiro na GPU durante o treinamento, e a serialização→envio acontece sem nunca voltar para a RAM do host. Latência típica: 1-10 ms para 100 MB.

Web (via Genie.jl / Oxygen.jl / HTTP.jl)

Para dashboards de observabilidade, use Genie.jl (similar a Phoenix para Elixir) ou Oxygen.jl:

using Oxygen
using Paebiru

@get "/healthz" function healthz()
    node = @__MODULE__.eval(:MESH_NODE)  # singleton global
    status = Paebiru.status(node)
    return status === :healthy ? "OK" : "DEGRADED"
end

@post "/messages" function send_message(req)
    body = json(req)
    target = body["target"]
    payload = body["payload"]
    node = @__MODULE__.eval(:MESH_NODE)
    receipt = Paebiru.send_message(node, target, payload)
    return json(receipt)
end

# Inicializa o nó PAEBIRU e o servidor
MESH_NODE = Paebiru.Node("./storage")
Paebiru.start(MESH_NODE)

serve(host="0.0.0.0", port=1975)

Bioinformatics (via BioJulia)

A org BioJulia mantém ecossistema de bioinformática 100% em Julia puro. O binding pode processar BioSequence ou Variation via compute-over-data:

using BioSequences
using Paebiru

# Alinhamento local Smith-Waterman em paralelo
function parallel_alignment(query::BioSequence, refs::Vector{BioSequence})
    node = Paebiru.Node("./storage")
    try
        for ref in refs
            # Envia o par query+ref como CausalBlock; plasmídeo
            # WASM faz o alinhamento no nó remoto
            send_message(node, "aln-worker", serialize((query, ref));
                         plasmid="smith-waterman.local.v1")
        end
    finally
        close(node)
    end
end

5. Veja também

🧮 Fortran (paebiru-fortran)

O binding Fortran é o mais antigo entre os 20+ do projeto (a linguagem data de 1957, dois anos antes do COBOL) e o canônico de HPC (High Performance Computing): supercomputadores Top500 rodam Fortran em workloads de modelagem climática (ECMWF, NOAA, GFS), CFD (ANSYS Fluent, OpenFOAM), física nuclear (CERN, ITER), química computacional (VASP, Gaussian), dinâmica molecular (GROMACS, NAMD), e modelagem financeira quantitativa. O PAEBIRU em Fortran é a porta de entrada honesta para esses sistemas — onde cada mesh emit Recibos Soberanos de medições, simulações, e decisões de controle.

O binding usa o módulo intrínseco iso_c_binding (Fortran 2003+) e o atributo bind(c) para vincular paebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com type(c_ptr) para handles opacos, coarray (Fortran 2008+) para paralelismo distribuído entre nós do supercomputador, e do concurrent para paralelismo intra-node com semântica SIMD/OpenMP.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via type(c_ptr): instâncias nativas (nó, identidade, recibo) são representadas como type(c_ptr) — o tipo canônico Fortran para ponteiros opacos vindos de C. Encapsuladas em uma type :: paebiru_node_t (tipo derivado) que mantém o handle em um campo privado. Cleanup via final binding (Fortran 2018+) ou manual.
  • Convenção de nomenclatura:
    • Tipos derivados e procedures em snake_case (estilo moderno) ou lowercase (estilo legacy) — comunidade Fortran está migrando para snake_case.
    • Variáveis, constantes em snake_case (storage_path, micro_joules).
    • Módulos em snake_case ou PascalCase (community- divided; fpm favorece snake_case).
    • Constantes em snake_case ou UPPER_SNAKE (depende do estilo).
    • Sufixos: kind para precisão de tipo (integer(c_int32_t)), len para comprimento de string (character(len=*)).
  • Gerenciamento de memória: type, bind(c) :: paebiru_node_t com membro type(c_ptr) :: handle = c_null_ptr. Cleanup via final :: cleanup_node (Fortran 2018+) chama paebiru_node_destroy quando o objeto sai de escopo.
  • Distribuição: package fpm (fpm install paebiru) no Fortran-lang registry. Configuração via fpm.toml (TOML, mesmo formato do Cargo).
  • C interop com iso_c_binding + bind(c): tipo canônico para interop. integer(c_int), real(c_double), character(kind=c_char), type(c_ptr), type(c_funptr). bind(c, name="c_name") para declarar uma rotina Fortran que mapeia para nome C específico.
  • Coarray para paralelismo distribuído (Fortran 2008+): integer :: counter [*] declara uma variável que existe em cada “image” (processo MPI). sync images([1,3]) para sincronizar. Mapeia diretamente para topologia de mesh PAEBIRU.
  • do concurrent para paralelismo intra-node (Fortran 2008+): do concurrent (i=1:n) ... end do é semanticamente puro (sem dependência de iteração) e o compilador pode paralelizar via SIMD/OpenMP. pure e elemental marcam funções como livres de side effects / vetorizáveis.
  • Array notation Fortran 90+: a(1:n) = b(1:n) * c(1:n) sem loops explícitos — toda a operação vetorizada automaticamente. Casa com hot-path de mesh.
  • Modules (Fortran 90+): encapsulamento forte com private/public. Substitui common blocks e arquivos .h de F77.
  • Derived types com type, bind(c) (Fortran 2003+): para C interop, tipos derivados podem ser bind(c) para garantir layout idêntico ao struct C.
  • Abstract interface (Fortran 2003+): para callbacks tipados. abstract interface + procedure(interface_name) ::
    • bind(c) para C function pointers.

2. Instalação

Aguardando primeira publicação no Fortran-lang registry. Quando disponível:

Via fpm (recomendado)

# Instalar fpm (Fortran Package Manager)
curl -fsSL https://github.com/fortran-lang/fpm/releases/download/v0.10.0/fpm-0.10.0-linux-x86_64.tar.xz \
     | tar -xJ
export PATH=$PATH:$HOME/.local/bin

# Criar novo projeto fpm
fpm new paebiru-app
cd paebiru-app

# Adicionar paebiru como dependência em fpm.toml
cat >> fpm.toml << EOF
[dependencies]
paebiru = "*"
EOF

# Compilar e rodar
fpm run

Via Makefile (projetos legados)

FC = gfortran
FFLAGS = -std=f2018 -O3 -fopenmp
LDFLAGS = -L/usr/local/lib -lpaebiru

%.o: %.f90
	$(FC) $(FFLAGS) -c $<

paebiru_app: main.o mesh.o
	$(FC) $(FFLAGS) -o $@ $^ $(LDFLAGS)

all: paebiru_app
clean: rm -f *.o paebiru_app

Verificação

fpm run
# ou
./paebiru_app

Dependências runtime

  • GFortran ≥ 13 (GCC, open-source) — primário
  • ifx ou ifort (Intel oneAPI) — secundário, alto desempenho
  • nvfortran (NVIDIA HPC SDK) — GPU via OpenACC/OpenMP target
  • fpm ≥ 0.10 (Fortran Package Manager) — recomendado
  • Sistema: libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows) — linkada via -lpaebiru

3. Exemplo de Uso

Módulo FFI (paebiru_ffi)

! src/paebiru_ffi.f90
module paebiru_ffi
  use, intrinsic :: iso_c_binding
  implicit none

  private
  public :: paebiru_node_create, paebiru_node_start
  public :: paebiru_node_send_message, paebiru_node_destroy
  public :: c_paebiru_receipt_t

  ! Tipos espelhando paebiru-c
  type, bind(c) :: c_paebiru_receipt_t
     character(kind=c_char) :: cid(64)   ! 32 bytes hex + null
     integer(c_int64_t)     :: micro_joules
     logical(c_bool)        :: is_healthy
  end type c_paebiru_receipt_t

  ! Declarações C interop
  interface
     ! Paebiru_Node_Create(Path) -> Handle (c_ptr)
     function paebiru_node_create(path) result(handle) &
          bind(c, name="paebiru_node_create")
       import :: c_ptr, c_char
       character(kind=c_char), intent(in) :: path(*)
       type(c_ptr) :: handle
     end function paebiru_node_create

     ! Paebiru_Node_Start(Handle) -> Rc (c_int)
     function paebiru_node_start(handle) result(rc) &
          bind(c, name="paebiru_node_start")
       import :: c_ptr, c_int
       type(c_ptr), value :: handle
       integer(c_int) :: rc
     end function paebiru_node_start

     ! Paebiru_Node_Send_Message(Handle, Target, ..., Receipt, ...) -> Rc
     function paebiru_node_send_message(handle, target, target_len, &
                                        payload, payload_len, &
                                        receipt_out) result(rc) &
          bind(c, name="paebiru_node_send_message")
       import :: c_ptr, c_char, c_size_t, c_int
       type(c_ptr), value :: handle
       character(kind=c_char), intent(in) :: target(*)
       integer(c_size_t), value :: target_len
       type(c_ptr), value :: payload
       integer(c_size_t), value :: payload_len
       type(c_ptr), value :: receipt_out
       integer(c_int) :: rc
     end function paebiru_node_send_message

     ! Paebiru_Node_Destroy(Handle)
     subroutine paebiru_node_destroy(handle) &
          bind(c, name="paebiru_node_destroy")
       import :: c_ptr
       type(c_ptr), value :: handle
     end subroutine paebiru_node_destroy
  end interface

end module paebiru_ffi

Tipo derivado paebiru_node_t (wrapper type-safe)

! src/paebiru_node.f90
module paebiru_node
  use, intrinsic :: iso_c_binding
  use paebiru_ffi
  implicit none

  private
  public :: paebiru_node_t, create_node, start_node, stop_node
  public :: send_message
  public :: paebiru_receipt_t

  ! Tipo opaco Fortran envolvendo c_ptr
  type :: paebiru_node_t
     private
     type(c_ptr) :: handle = c_null_ptr
   contains
     final :: cleanup_node
  end type paebiru_node_t

  ! Recibo Soberano (type-safe, layout compatível com C)
  type, bind(c) :: paebiru_receipt_t
     character(len=64) :: cid
     integer(c_int64_t) :: micro_joules
     logical(c_bool)    :: is_healthy
  end type paebiru_receipt_t

  interface
     ! Abstract interface para callbacks
     subroutine mesh_event_handler(event) bind(c)
       import :: c_int
       integer(c_int), intent(in) :: event
     end subroutine
  end interface

contains

  ! Finalizer — Fortran 2018+
  subroutine cleanup_node(self)
    type(paebiru_node_t), intent(inout) :: self
    if (c_associated(self%handle)) then
       call paebiru_node_destroy(self%handle)
       self%handle = c_null_ptr
    end if
  end subroutine cleanup_node

  ! Smart constructor
  function create_node(storage_path) result(node)
    character(len=*), intent(in) :: storage_path
    type(paebiru_node_t) :: node
    character(len=len(storage_path)+1) :: c_path
    integer :: i

    ! Converte Fortran string (sem null terminator) para C string
    do i = 1, len(storage_path)
       c_path(i:i) = storage_path(i:i)
    end do
    c_path(len(storage_path)+1:len(storage_path)+1) = c_null_char

    node%handle = paebiru_node_create(c_path)
    if (.not. c_associated(node%handle)) then
       error stop "paebiru_node_create returned NULL"
    end if
  end function create_node

  function start_node(node) result(rc)
    type(paebiru_node_t), intent(inout) :: node
    integer(c_int) :: rc

    rc = paebiru_node_start(node%handle)
  end function start_node

  function send_message(node, target, payload) result(receipt)
    type(paebiru_node_t), intent(inout) :: node
    character(len=*), intent(in) :: target
    character(len=*), intent(in) :: payload
    type(paebiru_receipt_t) :: receipt
    integer(c_int) :: rc

    type(c_paebiru_receipt_t) :: c_receipt
    character(len=len(target)+1) :: c_target
    character(len=len(payload)) :: c_payload  ! zero-copy via c_loc

    do i = 1, len(target)
       c_target(i:i) = target(i:i)
    end do
    c_target(len(target)+1:len(target)+1) = c_null_char

    rc = paebiru_node_send_message( &
         node%handle,                      &
         c_target,                         &
         int(len(target), c_size_t),       &
         c_loc(c_payload),                 &  ! zero-copy
         int(len(payload), c_size_t),      &
         c_loc(c_receipt))                   ! zero-copy out

    if (rc /= 0) then
       error stop "paebiru_node_send_message failed"
    end if

    ! Converte C receipt para Fortran type-safe
    receipt%cid           = transfer(c_receipt%cid, receipt%cid)
    receipt%micro_joules  = c_receipt%micro_joules
    receipt%is_healthy    = c_receipt%is_healthy
  end function send_message

end module paebiru_node

Programa principal (programação clássica)

! src/main.f90
program paebiru_app
  use paebiru_node
  implicit none

  type(paebiru_node_t) :: node
  type(paebiru_receipt_t) :: receipt
  integer(c_int) :: rc

  ! Inicializa nó (cleanup automático via final)
  node = create_node("/var/lib/paebiru")

  rc = start_node(node)
  if (rc /= 0) error stop "paebiru_node_start failed"

  ! Envia mensagem e recebe Recibo Soberano
  receipt = send_message(node, "audit_mesh", "hello from fortran")

  print '(A,A)', "Receipt CID : ", trim(receipt%cid)
  print '(A,I0)', "Custo µJ     : ", receipt%micro_joules
  print '(A,L1)', "Algedonic OK : ", receipt%is_healthy

  ! Cleanup automático quando 'node' sair de escopo
end program paebiru_app

Versão com coarray (paralelismo distribuído Fortran 2008+)

Coarray Fortran é o equivalente nativo de MPI — mapeia diretamente para topologia de mesh PAEBIRU:

! src/mesh_coarray.f90
module mesh_coarray
  use, intrinsic :: iso_c_binding
  use paebiru_node
  implicit none

  integer :: num_images         ! total de processos MPI
  integer :: this_image_num     ! ID deste processo
  type(paebiru_node_t), save :: nodes[*]  ! coarray: um nó por image

contains

  subroutine init_mesh(storage_path)
    character(len=*), intent(in) :: storage_path
    integer :: i

    num_images      = num_images()
    this_image_num  = this_image()

    ! Cada image cria seu próprio nó PAEBIRU
    nodes(this_image_num) = create_node( &
         trim(storage_path) // "_" // int_to_str(this_image_num))

    rc = start_node(nodes(this_image_num))
    if (rc /= 0) error stop "paebiru_node_start failed"

    ! Sincroniza todos os nós
    sync all
  end subroutine init_mesh

  function broadcast_receipt(receipt) result(all_receipts)
    type(paebiru_receipt_t), intent(in) :: receipt
    type(paebiru_receipt_t) :: all_receipts(num_images)

    ! Cada image envia seu receipt para todas as outras
    all_receipts(this_image_num) = receipt
    sync all

    ! Coleta receipts de outras images
    do i = 1, num_images
       if (i /= this_image_num) then
          all_receipts(i) = nodes(i)%last_receipt
       end if
    end do
  end function broadcast_receipt

  function int_to_str(i) result(s)
    integer, intent(in) :: i
    character(len=10) :: s
    write(s, '(I0)') i
  end function int_to_str

end module mesh_coarray

Versão com do concurrent + pure (vetorização SIMD)

pure function process_mesh_batch(payloads) result(receipts)
  type(c_ptr), intent(in) :: payloads(:)
  type(paebiru_receipt_t) :: receipts(size(payloads))
  integer :: i
  type(paebiru_node_t) :: local_node

  ! do concurrent: paralelismo automático, vetorizável
  do concurrent (i = 1:size(payloads))
     ! Cada iteração envia uma mensagem independente
     receipts(i) = send_message(local_node, "batch_target", payloads(i))
  end do
end function process_mesh_batch

4. Integração com HPC, Coarray e OpenMP/OpenACC

HPC: Langevin Dynamics (MCMC via OpenMP target offload)

! src/langevin_hpc.f90
module langevin_hpc
  use, intrinsic :: iso_c_binding
  use omp_lib
  use paebiru_node
  implicit none

contains

  ! SDE solver: dX = -∇U(X) dt + σ dW_t
  subroutine langevin_step(states, gradient_func, n_particles, dt, sigma)
    real(c_double), intent(inout) :: states(:, :)
    real(c_double), intent(in)    :: dt, sigma
    integer, intent(in)           :: n_particles
    interface
       pure function gradient_func(x) result(g)
         import :: c_double
         real(c_double), intent(in) :: x(:)
         real(c_double) :: g(size(x))
       end function gradient_func
    end interface

    real(c_double) :: noise(states)
    integer :: i
    type(paebiru_node_t) :: mesh_node
    type(paebiru_receipt_t) :: receipt

    mesh_node = create_node("/scratch/paebiru-langevin")
    rc = start_node(mesh_node)

    ! OpenMP parallel: cada thread processa partícula independente
    !$OMP PARALLEL DO PRIVATE(i, noise) SHARED(states)
    do i = 1, n_particles
       call random_number(noise)
       states(i, :) = states(i, :) - dt * gradient_func(states(i, :)) + &
                      sigma * sqrt(dt) * noise
    end do
    !$OMP END PARALLEL DO

    ! Envia trajetórias como CausalBlock (apenas 1% das amostras)
    do i = 1, n_particles, n_particles / 100
       receipt = send_message(mesh_node, "scheduler", &
            transfer(states(i, :), " ", size(states(i, :) * 8)))
    end do
  end subroutine langevin_step

end module langevin_hpc

GPU via OpenMP Target (nvfortran, AMD aomp)

subroutine gpu_langevin(states, n)
  real(c_double), intent(inout) :: states(:, :)
  integer, intent(in) :: n
  integer :: i

  ! Offload para GPU (NVIDIA via nvfortran, AMD via aomp)
  !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO
  do i = 1, n
     states(i, 1) = states(i, 1) * 2.0_c_double
     states(i, 2) = states(i, 2) + 1.0_c_double
  end do
  !$OMP END TARGET TEAMS DISTRIBUTE PARALLEL DO
end subroutine gpu_langevin

Coarray distribuído (PGAS, alternativa a MPI)

Coarray é o equivalente Fortran de MPI (PGAS — Partitioned Global Address Space). Casa nativamente com a topologia de mesh PAEBIRU:

! Compilar com coarray: gfortran -fcoarray=lib
program coarray_mesh
  use, intrinsic :: iso_c_binding
  use paebiru_node
  implicit none

  ! Coarray: cada image (processo MPI) tem seu próprio nó
  type(paebiru_node_t) :: nodes[*]
  type(paebiru_receipt_t) :: receipt, all_receipts[*]
  integer :: i

  ! Inicializa nó local
  nodes = create_node("/tmp/paebiru")

  ! Cada image envia uma mensagem
  receipt = send_message(nodes, "global_audit", &
       "image " // int_to_str(this_image()) // " reporting")

  ! Coloca receipt no coarray para acesso por outras images
  all_receipts[this_image()] = receipt

  ! Sincroniza todas as images
  sync all

  ! Cada image vê todos os receipts
  do i = 1, num_images()
     print '(A,I0,A,A)', "[Image ", this_image(), &
           "] Got receipt: ", trim(all_receipts[i]%cid)
  end do
end program coarray_mesh

MPI puro (alternativa a Coarray)

program mpi_mesh
  use mpi
  use paebiru_node
  implicit none

  integer :: rank, size, ierr
  type(paebiru_node_t) :: node
  type(paebiru_receipt_t) :: local_receipt, gathered_receipts(0:15)

  call MPI_Init(ierr)
  call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
  call MPI_Comm_size(MPI_COMM_WORLD, size, ierr)

  node = create_node("/tmp/paebiru-rank-" // int_to_str(rank))
  rc = start_node(node)
  local_receipt = send_message(node, "global_audit", "rank " // int_to_str(rank))

  ! MPI_Gather para coletar receipts de todos os ranks
  call MPI_Gather(local_receipt, sizeof(local_receipt), MPI_BYTE, &
                  gathered_receipts, sizeof(local_receipt), MPI_BYTE, &
                  0, MPI_COMM_WORLD, ierr)

  if (rank == 0) then
     print '(A,I0)', "Gathered ", size, " receipts"
  end if

  call MPI_Finalize(ierr)
end program mpi_mesh

fpm.toml (configuração do projeto)

[package]
name = "paebiru-hpc-app"
version = "0.1.0"
description = "HPC application using PAEBIRU mesh"
authors = ["HPC Team <hpc@example.org>"]
license = "AGPL-3.0-or-later"

[build]
auto-examples = true
auto-tests = true
auto-benchmarks = false

[dependencies]
paebiru = ">=0.1.0"

[fortran]
implicit-typing = false
implicit-external = false

[[executable]]
name = "paebiru-hpc-app"
source-dir = "src"

[target.openmp]
link = ["gomp"]

[target.cuda]
link = ["cudart", "openacc"]

5. Veja também

🟦 MATLAB/Octave (paebiru-matlab)

O binding MATLAB é o primeiro entre os 21+ que é comercial (com Octave como alternativa 100% open-source e ABI-compatível em nível de source). MATLAB é o canônico de engenharia de controle, processamento de sinais, visão computacional, modelagem financeira, GNC aeroespacial, e robótica — campos onde o PAEBIRU fornece auditabilidade de malha (Recibos Soberanos) que casa com a cultura de safety/audit já existente nesses domínios.

O binding é implementado como MEX file (MATLAB Executable) escrito em C/C++, que vincula paebiru-c e expõe funções que MATLAB chama diretamente — o mesmo modelo usado por qualquer toolbox nativa do MATLAB. Segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com mxArray para dados, mexMakeMemoryPersistent + mexMakeArrayPersistent para ownership de handles, e parfor/spmd/gpuArray para paralelismo nativo do Parallel Computing Toolbox.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via mxArray com tag persistente: instâncias nativas (nó, identidade, recibo) são representadas como mxArray* com mexMakeMemoryPersistent + tag custom para evitar GC do MATLAB. O handle C é armazenado no mxGetData(mx) (ou mxGetPr para double). Cleanup via mexAtExit registra função que chama paebiru_node_destroy para todos os handles ainda ativos no shutdown do MATLAB.
  • Convenção de nomenclatura:
    • Funções em snake_case (compat Octave) ou camelCase (estilo MATLAB moderno) — ambos suportados; recomendado snake_case para consistência com paebiru-c.
    • Variáveis em camelCase (convenção MATLAB).
    • Classes em PascalCase (PaebiruNode, PaebiruReceipt).
    • Constantes em UPPER_SNAKE_CASE (PAEBIRU_DEFAULT_PORT).
    • Properties de classe com validação: properties, Access = {?handle, ?isValid})
  • Gerenciamento de memória: handles armazenados em mxArray persistente; cleanup via mexAtExit + método delete() na classe wrapper. mexMakeArrayPersistent é obrigatório para que o GC do MATLAB não colete o handle.
  • Distribuição: MATLAB Add-On/Toolbox (.mltbx) para MATLAB; ou FEX submission (File Exchange) para download gratuito. Para Octave, Octave-Forge package (.tar.gz via pkg install).
  • MEX C/C++ API: mex.h (C) ou mex.hpp (C++ moderno). mexFunction(nlhs, plhs, nrhs, prhs) é o entry point. mxCreateNumericMatrix, mxGetPr, mxGetData, mxArrayToString, mexCallMATLAB, mexEvalString.
  • Class wrapper MATLAB: classe PaebiruNode com classdef que chama MEX internamente — expõe API OO para usuários MATLAB/Octave.
  • Event-driven com addlistener + timer: para consumir eventos de malha de forma assíncrona, use timer + addlistener (evento) + callback function handle.
  • Parallel computing nativo:
    • parfor (parallel for-loop) — equivalente a do concurrent Fortran ou OpenMP parallel for.
    • spmd (single program, multiple data) — equivalente a coarray Fortran ou MPI SPMD.
    • parcluster para configurar o cluster local/cloud.
    • distributed array type para arrays em pool de workers.
  • GPU computing: gpuArray para arrays em GPU (NVIDIA CUDA via Parallel Computing Toolbox, AMD ROCm via MATLAB Coder, Apple Metal limitado).
  • Code generation: MATLAB Coder gera C/C++ standalone do MATLAB; o binding pode ser usado em C/C++ gerado.
  • Simulink: blocos S-Function podem chamar MEX diretamente — para integrar PAEBIRU em modelos Simulink de controle.

2. Instalação

Aguardando primeira publicação no FEX / Octave-Forge. Quando disponível:

Via MATLAB Add-On (.mltbx)

MATLAB → Home → Add-Ons → Get Add-Ons → buscar "Paebiru" → Install

Ou download direto:

% No MATLAB
addpath(genpath('paebiru-matlab'))
savepath

Via File Exchange (FEX, gratuito)

% No MATLAB, abrir File Exchange
web('https://www.mathworks.com/matlabcentral/fileexchange/')
% Buscar "paebiru", baixar, instalar.

Via Octave (open-source)

# Octave 8.0+
octave --no-gui
pkg install paebiru-octave-0.1.0.tar.gz
pkg load paebiru

Compilação manual do MEX (a partir do source)

# MATLAB
mex -setup C++          # configura compilador (gcc/clang/MSVC)
mex CFLAGS="$CFLAGS -std=c++17 -O3" \
     -lpaebiru -I/usr/local/include \
     src/paebiru_node_create.cpp -o paebiru_node_create

# Octave
mkoctfile --mex paebiru_node_create.cpp -lpaebiru

Verificação

% No MATLAB/Octave
addpath('paebiru-matlab')
node = paebiru.node_create('/var/lib/paebiru');
disp(node)

Dependências runtime

  • MATLAB R2023a+ (primário) ou GNU Octave 8.0+ (open-source)
  • MEX C/C++ compiler: gcc, clang, MSVC, ou Intel oneAPI
  • Parallel Computing Toolbox (opcional, para parfor/spmd)
  • GPU support (opcional): NVIDIA CUDA 11+ ou AMD ROCm 5+
  • Sistema: libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows) — linkada via -lpaebiru

3. Exemplo de Uso

MEX C++ file (a base do binding)

// src/paebiru_node_create.cpp
#include "mex.h"
#include "matrix.h"
#include <cstring>
#include <unordered_map>
#include <cstdint>

// Declarações C do paebiru-c
extern "C" {
    void* paebiru_node_create(const char* path);
    int   paebiru_node_start(void* handle);
    int   paebiru_node_send_message(
        void* handle,
        const char* target, size_t target_len,
        const uint8_t* payload, size_t payload_len,
        void* receipt_out);
    void  paebiru_node_destroy(void* handle);
}

// Tabela global de handles ativos (cleanup em mexAtExit)
static std::unordered_map<uint64_t, void*> g_handles;
static uint64_t g_next_handle_id = 1;

static void cleanup_all_handles() {
    for (auto& [id, ptr] : g_handles) {
        paebiru_node_destroy(ptr);
    }
    g_handles.clear();
}

void mexFunction(int nlhs, mxArray* plhs[],
                 int nrhs, const mxArray* prhs[]) {
    // Registrar cleanup no shutdown
    static bool registered = false;
    if (!registered) {
        mexAtExit(cleanup_all_handles);
        registered = true;
    }

    if (nrhs < 1 || !mxIsChar(prhs[0])) {
        mexErrMsgIdAndTxt("Paebiru:node_create",
                          "Expected storage path as first arg");
        return;
    }

    char storage_path[1024];
    if (mxGetString(prhs[0], storage_path, sizeof(storage_path)) != 0) {
        mexErrMsgIdAndTxt("Paebiru:node_create",
                          "Storage path too long (max 1024)");
        return;
    }

    // Chama paebiru-c
    void* raw = paebiru_node_create(storage_path);
    if (!raw) {
        mexErrMsgIdAndTxt("Paebiru:node_create",
                          "paebiru_node_create returned NULL");
        return;
    }

    // Cria mxArray persistente para encapsular o handle
    uint64_t handle_id = g_next_handle_id++;
    g_handles[handle_id] = raw;

    // mxArray com 8 bytes do handle_id
    mwSize dims[2] = {1, 1};
    plhs[0] = mxCreateNumericArray(2, dims, mxUINT64_CLASS, mxREAL);
    mexMakeArrayPersistent(plhs[0]);
    uint64_t* data = static_cast<uint64_t*>(mxGetData(plhs[0]));
    *data = handle_id;
}
// src/paebiru_node_send_message.cpp
#include "mex.h"
#include "matrix.h"
#include <cstring>
#include <unordered_map>
#include <cstdint>

extern "C" {
    int paebiru_node_send_message(
        void* handle,
        const char* target, size_t target_len,
        const uint8_t* payload, size_t payload_len,
        void* receipt_out);
    void paebiru_node_destroy(void* handle);
}

// Acessa tabela global (em produção, usar shared lib)
extern std::unordered_map<uint64_t, void*> g_handles;

void mexFunction(int nlhs, mxArray* plhs[],
                 int nrhs, const mxArray* prhs[]) {
    if (nrhs < 3) {
        mexErrMsgIdAndTxt("Paebiru:send_message",
                          "Usage: paebiru_node_send_message(handle, target, payload)");
        return;
    }

    // Argumento 1: handle (mxArray com handle_id)
    if (!mxIsUint64(prhs[0])) {
        mexErrMsgIdAndTxt("Paebiru:send_message",
                          "First arg must be a paebiru handle");
        return;
    }
    uint64_t handle_id = *static_cast<uint64_t*>(mxGetData(prhs[0]));
    auto it = g_handles.find(handle_id);
    if (it == g_handles.end()) {
        mexErrMsgIdAndTxt("Paebiru:send_message",
                          "Invalid handle");
        return;
    }
    void* handle = it->second;

    // Argumento 2: target (string)
    char target[256];
    if (mxGetString(prhs[1], target, sizeof(target)) != 0) {
        mexErrMsgIdAndTxt("Paebiru:send_message",
                          "Target too long");
        return;
    }
    size_t target_len = strlen(target);

    // Argumento 3: payload (uint8 row vector, zero-copy)
    if (!mxIsUint8(prhs[2])) {
        mexErrMsgIdAndTxt("Paebiru:send_message",
                          "Payload must be uint8");
        return;
    }
    uint8_t* payload = static_cast<uint8_t*>(mxGetData(prhs[2]));
    size_t payload_len = mxGetNumberOfElements(prhs[2]);

    // Prepara receipt buffer
    struct {
        uint8_t  cid[64];
        uint64_t micro_joules;
        uint8_t  is_healthy;
    } receipt_buf;

    // Chama paebiru-c (zero-copy via ponteiro direto para mxArray data)
    int rc = paebiru_node_send_message(
        handle, target, target_len,
        payload, payload_len,
        &receipt_buf);
    if (rc != 0) {
        mexErrMsgIdAndTxt("Paebiru:send_message",
                          "paebiru_node_send_message failed: rc=%d", rc);
        return;
    }

    // Retorna struct MATLAB com cid, micro_joules, is_healthy
    const char* fields[] = {"cid", "micro_joules", "is_healthy"};
    plhs[0] = mxCreateStructMatrix(1, 1, 3, fields);
    mxSetField(plhs[0], 0, "cid",
               mxCreateString(reinterpret_cast<char*>(receipt_buf.cid)));
    mxSetField(plhs[0], 0, "micro_joules",
               mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL));
    *mxGetUint64s(mxGetField(plhs[0], 0, "micro_joules")) = receipt_buf.micro_joules;
    mxSetField(plhs[0], 0, "is_healthy",
               mxCreateLogicalScalar(receipt_buf.is_healthy != 0));
}

Classe wrapper MATLAB (OO API)

% src/+paebiru/Node.m (MATLAB classdef)
classdef Node < handle
    %PAEBIRU.NODE Wrapper OO para o nó PAEBIRU via MEX
    %   Use: node = paebiru.Node('/var/lib/paebiru')

    properties (SetAccess = private, GetAccess = public)
        Handle   uint64
        Storage  string
        IsValid  logical
    end

    properties (Access = private)
        EventListeners  event.listener
    end

    events
        PeerConnected
        PeerLost
        ReceiptProduced
    end

    methods
        function obj = Node(storage_path)
            % Construtor — chama MEX paebiru_node_create
            obj.Storage = string(storage_path);
            obj.Handle = paebiru_mex('node_create', char(obj.Storage));
            obj.IsValid = true;
        end

        function delete(obj)
            % Cleanup — chama MEX paebiru_node_destroy
            if obj.IsValid
                paebiru_mex('node_destroy', obj.Handle);
                obj.IsValid = false;
            end
        end

        function start(obj)
            rc = paebiru_mex('node_start', obj.Handle);
            if rc ~= 0
                error('Paebiru:start', 'paebiru_node_start failed: rc=%d', rc);
            end
        end

        function receipt = sendMessage(obj, target, payload)
            % Envia mensagem e retorna Recibo Soberano
            arguments
                obj
                target   string
                payload  uint8
            end
            if ischar(payload) || isstring(payload)
                payload = uint8(payload);
            end
            receipt = paebiru_mex('node_send_message', ...
                                  obj.Handle, ...
                                  char(target), ...
                                  payload);
        end

        function subscribe(obj, callback)
            % Subscreve a eventos de malha
            arguments
                obj
                callback  function_handle
            end
            addlistener(obj, {'PeerConnected', 'PeerLost', 'ReceiptProduced'}, ...
                       @(src, evt) callback(evt));
        end
    end
end

Programa principal (estilo MATLAB idiomático)

% examples/hello_paebiru.m
% Adicionar path do binding
addpath(genpath('paebiru-matlab'));

% Criar nó (cleanup automático via delete())
node = paebiru.Node('/var/lib/paebiru');
node.start();

% Subscrever a eventos
node.subscribe(@(evt) fprintf('[Event %s] %s\n', evt.EventName, evt.Data));

% Enviar mensagem e receber Recibo Soberano
receipt = node.sendMessage("audit_mesh", uint8('hello from MATLAB'));
fprintf('Receipt CID : %s\n', receipt.cid);
fprintf('Custo µJ     : %d\n', receipt.micro_joules);
fprintf('Algedonic OK : %d\n', receipt.is_healthy);

% Polling loop com timer (alternativa a addlistener)
t = timer('ExecutionMode', 'fixedRate', 'Period', 0.1, ...
          'TimerFcn', @(~,~) poll_events(node));
start(t);

% Cleanup explícito
pause(5);  % roda 5 segundos
stop(t); delete(t);
clear node;  % chama delete() automaticamente

parfor — paralelismo intra-node (Parallel Computing Toolbox)

% Computa FedAvg em paralelo com 8 workers
function weights = federated_train(local_datasets, global_weights)
    arguments
        local_datasets  cell
        global_weights   cell
    end

    % Configura cluster local
    if isempty(gcp('nocreate'))
        parpool('local', 8);
    end

    n = numel(local_datasets);
    local_deltas = cell(1, n);

    parfor i = 1:n
        % Cada worker: 1 nó PAEBIRU + 1 dataset local
        local_node = paebiru.Node(sprintf('/tmp/paebiru-worker-%d', i));
        local_node.start();
        delta = compute_local_delta(local_datasets{i}, global_weights);
        local_deltas{i} = delta;

        % Envia delta como CausalBlock
        receipt = local_node.sendMessage("coordinator", delta);
        fprintf('Worker %d: receipt %s\n', i, receipt.cid);
        clear local_node;  % cleanup
    end

    % Aggregação centralizada (FedAvg)
    weights = aggregate_fedavg(local_deltas);
end

spmd — paralelismo distribuído (SPMD = Single Program, Multiple Data)

% spmd é equivalente a coarray Fortran / MPI SPMD
function distributed_mesh(storage_root)
    if isempty(gcp('nocreate'))
        parpool('local', 16);  % 16 workers em cluster
    end

    spmd
        % Cada labindex (1..16) tem seu próprio nó
        my_node = paebiru.Node(fullfile(storage_root, sprintf('node-%d', labindex)));
        my_node.start();

        % Envia mensagem "hello" para todos os outros workers
        for target = 1:numlabs
            if target ~= labindex
                % labSend/labReceive: passagem de mensagem entre workers
                my_node.sendMessage(sprintf('worker-%d', target), uint8(sprintf('hello from %d', labindex)));
            end
        end

        % Cleanup
        clear my_node;
    end
end

gpuArray — paralelismo GPU (CUDA / ROCm)

% Arrays na GPU — zero cópia entre GPU e PAEBIRU (preparado)
function gpu_send_payload(node, gpu_payload)
    arguments
        node
        gpu_payload  gpuArray  % gpuArray automaticamente é uint8
    end
    % MATLAB faz gather() implícito ao passar gpuArray para uint8;
    % para zero-copy verdadeiro, use a versão MEX que recebe
    % gpuArray via mexGPU.
    payload = gather(gpu_payload);
    node.sendMessage("gpu_target", payload);
end

% Uso:
gpu_payload = gpuArray(uint8(randi(255, 1024, 1024)));  % 1 MB na GPU
node = paebiru.Node('/var/lib/paebiru');
gpu_send_payload(node, gpu_payload);

Para integrar PAEBIRU em modelos Simulink de controle (avião, robô, veículo autônomo):

  1. Crie um bloco S-Function que chama o MEX:
% paebiru_simulink_block.m
function paebiru_simulink_block(block)
    setup(block);

    % Portas de entrada/saída
    block.NumInputPorts  = 1;  % payload
    block.NumOutputPorts = 2;  % cid_out, mj_out

    block.SetInputPortDimensions(0, [1 1]);
    block.SetInputPortDataType(0, 'uint8');
    block.SetOutputPortDimensions(0, [1 32]);
    block.SetOutputPortDataType(0, 'uint8');
    block.SetOutputPortDimensions(1, [1 1]);
    block.SetOutputPortDataType(1, 'uint64');

    block.SampleTimes = [0.01 0];  % 100 Hz
    block.SimStateCompliance = 'DefaultSimState';

    block.RegBlockMethod('Outputs', @Outputs);
    block.RegBlockMethod('Terminate', @Terminate);
end

function Outputs(block)
    payload = block.InputPort(1).Data;
    % Chama MEX com payload atual
    receipt = paebiru_mex('node_send_message', ...
                          block.UserData.handle, ...
                          block.DialogPrm(1).Data, ...
                          payload);
    block.OutputPort(1).Data = uint8(receipt.cid);
    block.OutputPort(2).Data = receipt.micro_joules;
end

function Terminate(block)
    paebiru_mex('node_destroy', block.UserData.handle);
end
  1. Use o bloco em um modelo Simulink para GNC (Guidance, Navigation, Control) de um quadrotor, emitindo Recibos Soberanos a cada iteração de controle.

MATLAB Coder (gera C/C++ standalone)

% config.m
cfg = coder.config('lib');
cfg.TargetLang = 'C++';
cfg.GenerateReport = true;
cfg.HardwareImplementation.ProdHWDeviceType = 'Intel->x86-64 (Linux)';

% Gera código C++ standalone que chama paebiru_mex
codegen -config cfg hello_paebiru.m -l paebiru

% Resultado: hello_paebiru.cpp, hello_paebiru.h, e MEX compilado
% Pode ser embarcado em sistemas de controle real-time
% (autopiloto de drone, ECU automotivo, etc.) via MATLAB Coder

Octave (open-source, 100% compatível com MATLAB syntax)

% No Octave 8.0+
pkg load paebiru;

node = paebiru_node_create('/var/lib/paebiru');
paebiru_node_start(node);
receipt = paebiru_node_send_message(node, "audit", uint8("hello"));
disp(receipt.cid);

% Cleanup
paebiru_node_destroy(node);

5. Veja também

♨ Prolog (paebiru-prolog)

O binding Prolog é, entre os 22+ do projeto, o único baseado em lógica formal (cláusulas de Horn + resolução SLD) e o único com backtracking nativo como modelo de controle. Prolog é a linguagem canônica de IA simbólica, expert systems, theorem proving, NLP, knowledge graphs, e constraint satisfaction — todos domínios onde PAEBIRU se beneficia de auditoria baseada em regras lógicas sobre Recibos Soberanos. Por exemplo: “se um recibo tem CausalBlock com maturidade Causal > MUS e ∆C → 0, então ele deve ser marcado para apoptose” — uma regra PAEBIRU expressa naturalmente em Prolog.

O binding usa SWI-Prolog (open-source, padrão de fato desde 1987) com foreign declarations + c_lib para vincular paebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com term_t para marshaling, PL_foreign_t para handles em foreign frame (com cleanup determinístico no backtracking), e Pengines para expor o nó PAEBIRU como API HTTP lógica.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via PL_blob_t + PL_foreign_t: instâncias nativas (nó, identidade, recibo) são representadas em Prolog como blobs registrados via PL_register_blob_type — Prolog gerencia o GC deles, e o release() callback chama paebiru_node_destroy quando o blob é coletado. Para handles temporários (dentro de um predicate), usa-se PL_open_foreign_frame + PL_rewind_foreign_frame para cleanup determinístico no backtracking.
  • Convenção de nomenclatura:
    • Predicados em snake_case (paebiru_node_create/2, send_message/3).
    • Variáveis em Snake_Case_Starting_Uppercase (StoragePath, Payload). Anônimas: _.
    • Átomos em lowercase ou snake_case (node, audit_mesh).
    • Módulos em lowercase (paebiru_core, paebiru_mesh, paebiru_receipt).
    • Convenção mode: + (input), - (output), ? (both), @ (não instanciado), ! (determinístico).
  • Gerenciamento de memória: PL_blob_t com release callback chama paebiru_node_destroy quando o blob é coletado pelo GC do Prolog. Para cleanup imediato, use setup_call_cleanup/3 ou at_halt/1.
  • Distribuição: pack SWI-Prolog (SWI-Prolog pack registry) — ?- pack_install(paebiru).. Build via CMake.
  • C interop via foreign + c_lib: o módulo declara :- use_foreign_library(foreign(paebiru_c)). e os predicates são declarados como :- foreign(paebiru_node_create(+string, -node_handle), c).. O c_lib(paebiru, [...]) no foreign file carrega libpaebiru.so.
  • Backtracking nativo: predicados que têm múltiplas soluções simplesmente declaram alternativas; Prolog backtracka automaticamente. Para cleanup em backtrack, use setup_call_cleanup/3 ou PL_open_foreign_frame no lado C.
  • Knowledge graph de Recibos Soberanos: cada recibo pode ser armazenado como fato Prolog (ex: receipt(cid, target, micro_joules, is_healthy).) e consultado por regras lógicas — o “audit trail” do PAEBIRU torna-se queryable.
  • CLP(FD) e CLP(R) (Constraint Logic Programming): use clpfd para auditoria discreta (ex: CIDs têm formato específico) e clpr para auditoria contínua (ex: micro_joules

    limiar).

  • Pengines (Prolog-as-a-Service): expõe predicados Prolog como API HTTP lógica — o cliente envia uma query e recebe JSON com soluções.
  • Tabling (memoization): :- table paebiru_receipt/1. cacheia resultados — útil para queries repetidas sobre a mesma mesh.

2. Instalação

Aguardando primeira publicação no SWI-Prolog pack. Quando disponível:

Via SWI-Prolog Pack

% No REPL SWI-Prolog (swipl)
?- pack_install(paebiru).

Via CMake (compilação manual do source)

# Instalar dependências
apt-get install swi-prolog cmake gcc

# Clonar e compilar
git clone https://github.com/paebiru/paebiru-prolog.git
cd paebiru-prolog
mkdir build && cd build
cmake ..
make
make install

Verificação

?- use_module(paebiru_core).
?- paebiru_node_create('/tmp/paebiru', Node).
?- paebiru_node_start(Node).
?- paebiru_node_send_message(Node, 'audit', 'hello', Receipt).
?- format("Receipt CID: ~w~n", [Receipt]).

Dependências runtime

  • SWI-Prolog ≥ 9.0 (open-source) — primário
  • libpaebiru.so (Linux) / .dylib (macOS) / .dll (Windows)
  • libc (sempre disponível)
  • Opcional: Pengines (incluído em SWI), CLP(FD), CLP(R) (incluídos em SWI)
  • Opcional para browser: Tau Prolog (via npm ou CDN)

3. Exemplo de Uso

Foreign C file (a base do binding)

/* src/foreign_paebiru.c */
#include <SWI-Prolog.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

/* Declarações do paebiru-c */
extern void* paebiru_node_create(const char* path);
extern int   paebiru_node_start(void* handle);
extern int   paebiru_node_send_message(
    void* handle,
    const char* target, size_t target_len,
    const uint8_t* payload, size_t payload_len,
    void* receipt_out);
extern void  paebiru_node_destroy(void* handle);

/* Blob type para o handle */
static int
release_node_blob(atom_t name)
{
    void *ptr;
    if (PL_get_blob(name, &ptr, NULL, NULL)) {
        paebiru_node_destroy(ptr);
        return TRUE;
    }
    return FALSE;
}

static PL_blob_t node_blob = {
    .magic     = PL_BLOB_MAGIC,
    .name      = "paebiru_node",
    .release   = release_node_blob,
    .compare   = NULL,
    .write     = NULL,
    .acquire   = NULL,
    .flags     = 0,
    .pad       = 0,
};

/* Install blob type at load */
static void
install_blob_types(void)
{
    PL_register_blob_type(&node_blob);
}

install_t install_paebiru =
   { 0, install_blob_types, NULL };

/* Foreign: paebiru_node_create(+StoragePath, -Node) */
static foreign_t
pl_paebiru_node_create(term_t StoragePath, term_t Node)
{
    char *path;
    if (!PL_get_atom_chars(StoragePath, &path))
        return PL_type_error("atom", StoragePath);

    void* handle = paebiru_node_create(path);
    if (!handle)
        return PL_existence_error("paebiru_node", StoragePath);

    /* Wrap handle in blob */
    if (!PL_unify_blob(Node, handle, strlen(path), &node_blob))
        return PL_no_memory();
    return TRUE;
}

/* Foreign: paebiru_node_start(+Node) */
static foreign_t
pl_paebiru_node_start(term_t Node)
{
    void *handle;
    if (!PL_get_blob(Node, &handle, NULL, NULL))
        return PL_type_error("paebiru_node", Node);

    int rc = paebiru_node_start(handle);
    if (rc != 0)
        return PL_uninstantiation_error(Node);
    return TRUE;
}

/* Foreign: paebiru_node_send_message(+Node, +Target, +Payload, -Receipt) */
static foreign_t
pl_paebiru_node_send_message(term_t Node, term_t Target, term_t Payload,
                              term_t Receipt)
{
    void *handle;
    char *target;
    term_t list = PL_copy_term_ref(Payload);
    term_t head = PL_new_term_ref();
    term_t list_head = PL_new_term_ref();

    if (!PL_get_blob(Node, &handle, NULL, NULL))
        return PL_type_error("paebiru_node", Node);
    if (!PL_get_atom_chars(Target, &target))
        return PL_type_error("atom", Target);

    /* Converte lista Prolog para buffer contíguo */
    size_t payload_len = 0;
    size_t buf_size = 1024;
    uint8_t *buf = malloc(buf_size);
    while (PL_get_list(list, head, list)) {
        if (PL_is_variable(head)) {
            free(buf);
            return PL_instantiation_error(head);
        }
        int byte;
        if (!PL_get_integer(head, &byte)) {
            free(buf);
            return PL_type_error("integer", head);
        }
        if (payload_len >= buf_size) {
            buf_size *= 2;
            buf = realloc(buf, buf_size);
        }
        buf[payload_len++] = (uint8_t)byte;
    }
    if (!PL_get_nil(list)) {
        free(buf);
        return PL_type_error("list", Payload);
    }

    /* Aloca receipt buffer no C heap */
    struct receipt_buf {
        uint8_t  cid[64];
        uint64_t micro_joules;
        uint8_t  is_healthy;
    } receipt;

    int rc = paebiru_node_send_message(
        handle, target, strlen(target),
        buf, payload_len, &receipt);
    free(buf);
    if (rc != 0) {
        return PL_uninstantiation_error(Node);
    }

    /* Unifica Receipt com termo Prolog `receipt(CID, MJ, Healthy)` */
    term_t cid_term = PL_new_term_ref();
    term_t mj_term  = PL_new_term_ref();
    term_t hp_term  = PL_new_term_ref();
    PL_put_atom_chars(cid_term, (const char*)receipt.cid);
    PL_put_uint64(mj_term, receipt.micro_joules);
    PL_put_bool(hp_term, receipt.is_healthy != 0);

    if (!PL_unify_term(Receipt,
        PL_FUNCTOR, PL_new_functor(PL_new_atom("receipt"), 3),
          cid_term, mj_term, hp_term))
        return FALSE;
    return TRUE;
}

/* Foreign: paebiru_node_destroy(+Node) */
static foreign_t
pl_paebiru_node_destroy(term_t Node)
{
    void *handle;
    if (!PL_get_blob(Node, &handle, NULL, NULL))
        return PL_type_error("paebiru_node", Node);
    paebiru_node_destroy(handle);
    PL_erase_blob(Node);
    return TRUE;
}

/* Tabela de funções para install */
#define PL_FA_FFI 0  /* sem flags especiais */

#define FUNC(name, arity) { (name), (arity), PL_FA_FFI, pl_ ## name, NULL }
#define PL_REG(name, arity) { "paebiru:" #name, (arity), \
                              PL_FA_VAR_ARGS | PL_FA_NONDETERMINISTIC, \
                              pl_paebiru_ ## name, NULL }

Install_t install_paebiru_funs[] = {
    PL_REG(node_create, 2),
    PL_REG(node_start, 1),
    PL_REG(node_send_message, 4),
    PL_REG(node_destroy, 1),
    NULL
};

/* install() é chamado quando o foreign file é carregado */
install_t
install(void)
{
    install_blob_types();
    PL_register_extensions_in_module("paebiru", install_paebiru_funs);
}

Módulo Prolog (paebiru_core)

% src/paebiru_core.pl
:- module(paebiru_core, [
      paebiru_node_create/2,
      paebiru_node_start/1,
      paebiru_node_send_message/4,
      paebiru_node_destroy/1
   ]).

:- use_foreign_library(foreign(paebiru_c)).

%! paebiru_node_create(+StoragePath, -Node) is det.
%
%  Cria nó PAEBIRU e unifica Node com um blob opaco.
%  Cleanup automático via blob release callback.
%
:- foreign(paebiru_node_create(+string, -node_handle)).

%! paebiru_node_start(+Node) is det.
%
%  Inicia o nó (sync).
:- foreign(paebiru_node_start(+node_handle)).

%! paebiru_node_send_message(+Node, +Target, +Payload, -Receipt) is det.
%
%  Envia mensagem e unifica Receipt com termo `receipt(CID, MJ, Healthy)`.
:- foreign(paebiru_node_send_message(+node_handle, +atom, +list(integer), -compound)).

%! paebiru_node_destroy(+Node) is det.
%
%  Cleanup explícito.
:- foreign(paebiru_node_destroy(+node_handle)).

Programa principal (estilo Prolog idiomático)

% examples/hello_paebiru.pl
:- use_module(paebiru_core).

main :-
    paebiru_node_create('/tmp/paebiru', Node),
    paebiru_node_start(Node),
    % Converte string para lista de bytes (payload)
    string_codes("hello", Payload),
    paebiru_node_send_message(Node, 'audit_mesh', Payload, Receipt),
    % Pattern match no recibo
    Receipt = receipt(CID, MicroJoules, IsHealthy),
    format("Receipt CID : ~w~n", [CID]),
    format("Custo µJ     : ~w~n", [MicroJoules]),
    format("Algedonic OK : ~w~n", [IsHealthy]),
    % Cleanup
    paebiru_node_destroy(Node).

:- main.

4. Integração com Knowledge Graphs, Pengines e CLP

Knowledge Graph de Recibos Soberanos (a força do Prolog)

% Cada recibo é um FATO Prolog (assert na base de conhecimento)
:- dynamic receipt/3.
:- dynamic peer/2.

% Inicializa base com peers
assert_peer :-
    assert(peer(audit_mesh,    'audit@paebiru.network')),
    assert(peer(coordinator,   'coord@paebiru.network')),
    assert(peer(observer_drone, 'drone1@paebiru.network')).

% Inicializa nó PAEBIRU
init_mesh :-
    assert_peer,
    paebiru_node_create('/var/lib/paebiru', Node),
    paebiru_node_start(Node),
    assert(node_handle(Node)).

% Envia mensagem para cada peer e armazena recibo
broadcast_to_all_peers :-
    init_mesh,
    node_handle(Node),
    receipt(Node, Peer, _) :-
        peer(Peer, _),
        string_codes("mesh announcement", Payload),
        paebiru_node_send_message(Node, Peer, Payload, R),
        R = receipt(CID, MJ, Healthy),
        assert(receipt(Peer, CID, MJ, Healthy)),
        format("Sent to ~w: CID=~w µJ=~d OK=~w~n",
               [Peer, CID, MJ, Healthy]),
        fail.  % força backtrack para próximo peer
    broadcast_to_all_peers.

% Regras de auditoria baseadas em Recibos Soberanos
% (aqui Prolog brilha — lógica de auditoria declarativa)

% Regra 1: peer saudável se todos seus receipts são algedonicamente OK
healthy_peer(Peer) :-
    \+ (receipt(Peer, _, _, false)).

% Regra 2: peer suspeito se tem mais de 3 receipts falhos
suspect_peer(Peer) :-
    findall(_, receipt(Peer, _, _, false), FailedReceipts),
    length(FailedReceipts, N),
    N > 3.

% Regra 3: peer confiável se tem >10 receipts OK E nenhum falho
trusted_peer(Peer) :-
    findall(_, receipt(Peer, _, _, true), OkReceipts),
    length(OkReceipts, N),
    N > 10,
    \+ (receipt(Peer, _, _, false)).

% Query: "Liste todos os peers confiáveis"
?- trusted_peer(Peer).
% Peer = audit_mesh
% Peer = coordinator
% ...

% Query: "Liste todos os peers suspeitos"
?- suspect_peer(Peer).
% Peer = observer_drone.

Pengines (Prolog-as-a-Service) — API HTTP lógica

Exponha predicados PAEBIRU como API web lógica:

% server.pl — Pengines server
:- use_module(library(pengines)).
:- use_module(paebiru_core).
:- use_module(audit_rules).

% Inicializa nó no startup do servidor
:- initialization(init_mesh).

% Pengine predicate: send_message(+Request, -Response)
:- pengine:export(pengines:safe_send_message/3).
:- pengine:export(pengines:audit_query/1).

% Cliente envia query + payload, servidor envia e retorna recibo
pengines:safe_send_message(Node, Request, Receipt) :-
    json_to_prolog(Request, PrologRequest),
    PrologRequest = json{atom:Target, payload:Payload},
    string_codes(Payload, PayloadCodes),
    paebiru_node_send_message(Node, Target, PayloadCodes, Receipt),
    format("Receipt: ~w~n", [Receipt]).

% Cliente envia query lógica, servidor retorna soluções
pengines:audit_query(Query) :-
    % Query é uma string Prolog; Prolog a executa
    term_to_atom(Term, Query),
    atom_concat('audit_rules:', Term, FullTerm),
    % Aplica regras de auditoria
    forall(call(FullTerm), true).

Cliente JavaScript:

// Cliente web usando pengines.js
const pengine = new Pengine({
    server: 'http://localhost:3030'
});

await pengine.ask('safe_send_message(Node, "audit_msg", Receipt)', {
    Node: '<blob_handle>'
});
console.log(pengine.answers[0].x);  // Receipt

// Query lógica via HTTP
await pengine.ask('audit_query(trusted_peer(Peer))', {
    template: 'Peer'
});
// returns ['audit_mesh', 'coordinator']

CLP(FD) — Constraint Logic Programming

Auditoria discreta com constraints sobre o Recibo Soberano:

:- use_module(library(clpfd)).

% Regra: Recibo válido se CID tem 64 chars hex E
%        micro_joules está em faixa razoável E
%        healthy é true
valid_receipt(receipt(CID, MJ, Healthy)) :-
    string_length(CID, 64),
    % Constraint: micro_joules entre 0 e 1000000
    MJ #> 0,
    MJ #< 1000000,
    Healthy = true.

% Query: encontre todos os receipts VÁLIDOS com MJ > 10000
?- valid_receipt(R), R = receipt(_, MJ, _), MJ #> 10000.

CLP(R) — Constraint Logic Programming sobre Reais

Auditoria contínua sobre propriedades do Recibo Soberano (ex: derivada de Langevin, custo termodinâmico):

:- use_module(library(clpr)).

% Regra: Recibo termodinamicamente válido se
%        µJ_consumido ≤ µJ_disponível
thermo_valid_receipt(Receipt, Available_J) :-
    Receipt = receipt(_, MicroJoules, Healthy),
    MicroJoules =< Available_J,
    Healthy = true.

% Query: em uma partição com budget de 1 joule,
%        quantos receipts cabem?
?- Available_J = 1.0,
   L = [R1, R2, R3, R4, R5],
   maplist(thermo_valid_receipt(.), L).
% Prolog resolve constraints automaticamente.

Tabling (memoization) — queries repetidas sobre a mesh

:- table receipt_for/3.
:- dynamic cached_receipt/3.

% Cacheia lookup de receipts (não recalcula se já viu)
receipt_for(Peer, CID, MicroJoules) :-
    cached_receipt(Peer, CID, MicroJoules), !.
receipt_for(Peer, CID, MicroJoules) :-
    paebiru_node_send_message(Node, Peer, "lookup", Receipt),
    Receipt = receipt(CID, MicroJoules, _),
    assert(cached_receipt(Peer, CID, MicroJoules)).

% Queries repetidas são instantâneas (memoized)
?- receipt_for('audit_mesh', CID, MJ).
% Segunda chamada: zero overhead (vem do cache)
?- receipt_for('audit_mesh', CID, MJ).

Constraint Handling Rules (CHR) — regras de auditoria

:- use_module(library(chr)).

% CHR rules para auditoria algedônica
:- chr_constraint
    healthy/1,
    failed/1,
    suspect/1,
    trusted/1.

% Regra: peer com 3+ falhas torna-se suspect
failed(Peer), failed(Peer), failed(Peer) ==>
    suspect(Peer).

% Regra: peer com 10+ sucessos e 0 falhas torna-se trusted
healthy(Peer), healthy(Peer), healthy(Peer),
healthy(Peer), healthy(Peer), healthy(Peer),
healthy(Peer), healthy(Peer), healthy(Peer),
healthy(Peer) \ failed_count(Peer, 0)
==> trusted(Peer).

5. Veja também

⚡ Zig (paebiru-zig)

O binding Zig é único entre os 14 do PAEBIRU: não usa uma crate Rust de FFI intermediária (como mlua, ext-php-rs, extendr, Magnus, UniFFI). Em vez disso, consome o paebiru-c diretamente via @cImport — a interoperabilidade C nativa do Zig. Esta escolha reflete a filosofia do próprio Zig: “C interop is not an afterthought; it’s the foundation.”

Alvos canônicos: sistemas operacionais (Zig é usado em kernels), build systems (Bun, TigerBeetle, zig standard library), engines de alta performance, firmware embarcado (freestanding mode), e qualquer lugar onde Rust

  • C já coexistem. Segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com alocadores explícitos (Zig não tem alocador escondido), errdefer para cleanup similar a try/finally, e comptime para abstrações zero-cost.

⚠️ Status atual (v0.0.2-0): apenas o crate paebiru-kernel está implementado. Os demais bindings são esqueleto (stubs TOML + manifest) e serão preenchidos em fases posteriores do roadmap.


1. Princípios de Design

  • Opaque Handles via *opaque {}: instâncias nativas (nó, identidade, recibo) são representadas em Zig como tipos opacos declarados com const PaebiruNode = opaque {}; (ou extern struct quando o layout precisa ser visível). O ponteiro *PaebiruNode é o handle — nunca o tipo em si.
  • Convenção de nomenclatura:
    • Tipos, structs, enums, unions em PascalCase (PaebiruNode, MeshEvent, Receipt).
    • Funções, variáveis, campos em snake_case (paebiru_node_create, send_message).
    • Constantes em UPPER_SNAKE_CASE (PAEBIRU_DEFAULT_PORT).
    • Zig não tem class — usa struct + funções livres (paebiru_node_start(node: *PaebiruNode) noreturn).
  • Gerenciamento de memória — alocadores explícitos: Zig não tem alocador escondido. Toda função que aloca recebe um parâmetro allocator: std.mem.Allocator. Para o binding PAEBIRU, a recomendação é std.heap.GeneralPurposeAllocator em desenvolvimento e std.heap.page_allocator (ou um ArenaAllocator scoped) em produção.
  • Cleanup via errdefer: padrão equivalente a try/finally: errdefer node.destroy(); garante que destroy é chamado se qualquer operação subsequente falhar.
  • Erros como valores: Zig usa error{X}!T (similar a Result<T, X> em Rust). O binding converte paebiru_* que retornam int em um error union Zig, ex: PaebiruError!Receipt.
  • Sem hidden control flow: Zig não tem exceções, operator overloading, ou construtores implícitos. Toda operação é visível no código-fonte — essencial para auditoria do ZeroTrustPipeline.
  • Tagged unions para MeshEvent: Zig’s union(enum) permite ADTs com payload, equivalente a enum Swift ou Rust:
    const MeshEvent = union(enum) {
        peer_connected: PeerId,
        peer_lost: struct { peer_id: PeerId, reason: []const u8 },
        receipt_produced: Receipt,
    };
    
  • comptime para zero-cost abstractions: funções genéricas com comptime T permitem polimorfismo sem custo de runtime: fn Wrapper(comptime T: type) type { return struct { ... }; }.
  • Build via build.zig: o pacote inclui um build.zig que vincula libpaebiru (C) e expõe módulos Zig. Dependências via build.zig.zon + zig fetch.

2. Instalação

Aguardando primeira publicação do paebiru-c como artefato redistribuível. Quando disponível:

Via build.zig.zon (Zig ≥ 0.12)

// build.zig.zon
.{
    .name = .paebiru_zig,
    .version = "0.1.0",
    .fingerprint = "...",
    .dependencies = .{
        .paebiru_c = .{
            .url = "https://github.com/paebiru/paebiru-c/archive/refs/tags/v0.1.0.tar.gz",
            .hash = "...",
        },
    },
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
    },
}
zig build

Via git submodule (Zig ≥ 0.11)

git submodule add https://github.com/paebiru/paebiru-c.git vendor/paebiru-c

Configure build.zig:

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    // Adiciona o caminho do header C
    const paebiru_c = b.addStaticLibrary(.{
        .name = "paebiru",
        .target = target,
        .optimize = optimize,
    });
    paebiru_c.addCSourceFile(.{ .file = .{ .cwd_relative = "vendor/paebiru-c/paebiru.c" } });
    paebiru_c.addIncludePath(.{ .cwd_relative = "vendor/paebiru-c/include" });
    paebiru_c.linkLibC();
    b.installArtifact(paebiru_c);

    // Cria o executável que consome paebiru
    const exe = b.addExecutable(.{
        .name = "myapp",
        .root_source_file = .{ .cwd_relative = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });
    exe.linkLibrary(paebiru_c);
    exe.linkLibC();
    b.installArtifact(exe);
}

Dependências runtime

  • Zig ≥ 0.13 (para std.Build, comptime maduro, union(enum))
  • Headers C do paebiru-c (paebiru.h)
  • libpaebiru estática (.a) ou dinâmica (.so/.dylib/.dll) empacotada como artefato redistribuível

3. Exemplo de Uso

API básica (alocador explícito + errdefer + tagged union)

// src/main.zig
const std = @import("std");
const c = @cImport({
    @cInclude("paebiru.h");
});

// Opaque types espelhando paebiru-c
const PaebiruNode = opaque {};
const Receipt = extern struct {
    cid: [32]u8,
    micro_joules: u64,
    is_algedonically_healthy: bool,
};

const MeshEvent = union(enum) {
    peer_connected: [*:0]const u8,  // peer_id como string C
    peer_lost: struct {
        peer_id: [*:0]const u8,
        reason: [*:0]const u8,
    },
    receipt_produced: Receipt,
};

const PaebiruError = error{
    OutOfMemory,
    InvalidArgument,
    NetworkDown,
    Unknown,
};

// Wrapper idiomático sobre a API C
const Node = struct {
    raw: *PaebiruNode,
    allocator: std.mem.Allocator,

    pub fn create(allocator: std.mem.Allocator, path: [*:0]const u8) PaebiruError!Node {
        const raw = c.paebiru_node_create(path) orelse return PaebiruError.OutOfMemory;
        errdefer c.paebiru_node_destroy(raw);
        return Node{ .raw = raw, .allocator = allocator };
    }

    pub fn start(self: Node) PaebiruError!void {
        if (c.paebiru_node_start(self.raw) != 0) return PaebiruError.Unknown;
    }

    pub fn sendMessage(
        self: Node,
        target: [*:0]const u8,
        payload: []const u8,
    ) PaebiruError!Receipt {
        var receipt: c.paebiru_receipt_t = undefined;
        const rc = c.paebiru_node_send_message(
            self.raw,
            target,
            payload.ptr,
            payload.len,
            &receipt,
        );
        if (rc != 0) return PaebiruError.Unknown;

        return Receipt{
            .cid = receipt.cid,
            .micro_joules = receipt.micro_joules,
            .is_algedonically_healthy = receipt.is_algedonically_healthy,
        };
    }

    pub fn destroy(self: Node) void {
        c.paebiru_node_destroy(self.raw);
    }
};

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var node = try Node.create(allocator, "./storage");
    defer node.destroy();
    errdefer node.destroy();  // safety net

    try node.start();

    const receipt = try node.sendMessage(
        "12D3KooW...",
        "hello",
    );

    std.debug.print("Receipt CID : {x}\n", .{receipt.cid});
    std.debug.print("Custo µJ     : {}\n", .{receipt.micro_joules});
    std.debug.print("Algedonic OK : {}\n", .{receipt.is_algedonically_healthy});
}

Versão com comptime para dispatcher de eventos

fn handleEvent(comptime Logger: type, event: MeshEvent) !void {
    switch (event) {
        .peer_connected => |peer_id| try Logger.log("peer up: {s}", .{peer_id}),
        .peer_lost => |info| try Logger.log("peer down: {s} ({s})", .{ info.peer_id, info.reason }),
        .receipt_produced => |receipt| try Logger.log("receipt: {x}", .{receipt.cid}),
    }
}

comptime Logger: type permite que o logger seja polimórfico em compile-time — sem custo de indireção em runtime, similar a generics C++ ou traits Rust.

Versão async/await (Zig 0.14, ainda experimental)

pub fn watchMesh(node: Node) !void {
    while (true) {
        const event = try node.awaitNextEvent();  // async fn
        try handleEvent(std.log, event);
    }
}

⚠️ async/await em Zig ainda está em redesign. Para hot-path de produção, use o modelo baseado em callback ou blocking I/O direto — Zig é uma linguagem para casos onde você quer controle fino.


4. Integração com Embedded (freestanding), Bun e Build Systems

Modo freestanding (sem libc, sem heap, bare-metal)

Zig pode compilar para alvos embarcados sem libc — útil para HAL embarcado e MuleNodes:

pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace) noreturn {
    // Em bare-metal, chame seu próprio panic handler
    while (true) {}
}

export fn _start() noreturn {
    // Inicializa nó sem alocador (heap opcional)
    const node = c.paebiru_node_create_static(null) orelse
        @panic("failed to create node");

    c.paebiru_node_start(node);
    while (true) {
        _ = c.paebiru_node_tick(node);
    }
}

Para integrar com paebiru-hal (HAL embarcado do PAEBIRU), o build.zig declara o target embarcado:

const hal_target = b.resolveTargetQuery(.{
    .cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m4 },
    .os_tag = .freestanding,
    .abi = .eabi,
    .ofmt = .elf,
});

Bun (build system + runtime JavaScript)

Bun é escrito em Zig e consome o binding para features de baixo nível (rede, FFI). O build.zig de Bun pode opcionalmente depender de paebiru-c para integrar P2P nativo:

const paebiru_dep = b.dependency("paebiru_c", .{
    .target = target,
    .optimize = optimize,
});
exe.linkLibrary(paebiru_dep.artifact("paebiru"));

Build systems e ferramentas de linha de comando

Zig é cada vez mais usado como linguagem de build (substituindo Make/CMake). Para ferramentas CLI que precisam de P2P nativo:

  • Use std.heap.ArenaAllocator no main e libere tudo de uma vez no final:
    pub fn main() !void {
        var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
        defer arena.deinit();
        const allocator = arena.allocator();
        // ... use allocator ...
    }
    
  • Combine com std.debug.print e std.log para output estruturado.
  • Para CLIs que precisam de P2P, o paebiru_node_send_message emite Recibos Soberanos de cada comando — auditabilidade ponto-a-ponto.

TigerBeetle-style (high-performance, single-writer)

Zig é a linguagem canônica para bancos de dados de alta performance estilo TigerBeetle (single-writer, log-structured, preemptible). O binding PAEBIRU pode ser usado em tal projeto para sincronização causal entre réplicas:

  • Use std.atomic.Value(T) para estado compartilhado.
  • Use std.Thread para workers com prioridade fixa.
  • Combine com std.posix.mmap para I/O zero-copy em hot-path.

5. Veja também

🎨 Identidade Visual — Livro de Estilo (UX)

A membrana estética do PAEBIRU: o conjunto de regras que garante que toda superfície — CLI, TUI, dashboards, site de documentação, identidade impressa, arte em mídias sociais — fale a mesma língua biológica, fractal e antropofágica do projeto.

Este documento é vinculante para qualquer artefato visual ou textual produzido em nome do PAEBIRU (documentação, screenshots, slides, posts, capas, ícones, mensagens de UI). Em caso de conflito com preferências pessoais, o livro de estilo vence. Em caso de conflito com outro documento, vence a hierarquia canônica do AGENTS.md: dictionary.md > este livro de estilo

RFCs Standards Track.


1. Filosofia & Princípios

1.1 Os três eixos estéticos

Toda decisão de UX no PAEBIRU é atravessada por três eixos co-derivados da Realidade fractal:

EixoManifestação em UX
BiológicoA interface imita membranas, metabolismo, sinais de dor/prazer (algedonia), homeostasia. Exemplo: um sensor que vibra verde quando saudável, esmaece para tons frios sob estresse, e pisca vermelho sob Veto Algedônico.
FractalO mesmo padrão ingerir → metabolizar → excretar aparece em todas as escalas: do pixel ao log de auditoria. Exemplo: o mesmo ícone de plasmídeo aparece em CLI (1 linha), TUI (caixa) e dashboard (página inteira) — apenas o nível de zoom muda.
AntropofágicoDevoramos referências (CLI Unix, dashboards Grafana, design system Iosevka) e devolvemos o que sobrou em forma de receipt rastreável. Exemplo: se copiamos uma convenção do cargo, registramos a fonte no AGENTS.md e a datamos.

1.2 Conexão com os 4 Dogmas

Os dogmas da RFC 050 têm tradução direta em UX. Tratar como restrição arquitetural (recusa automática em revisão):

  1. Isolamento Absoluto (Hexagonal) → Cada Bounded Context tem sua própria área visual (TUI tem painéis próprios; dashboard separa Kernel, Biologia, Economia, C.A.P.I.B.A.). Nada cruza a membrana sem um receipt visível (timestamp + assinatura).
  2. GALS & Actor-like State → Toda tela tem estado local observável (loading, idle, error) e nunca compartilha estado mutável com outra tela via canal implícito. Use eventos assíncronos, publique-os.
  3. Pragmatismo de Hardware (no_std First) → A CLI deve rodar em terminais de 80×24 (TTY legado, terminais seriais de MuleNode). Tabelas, cores e layouts que não cabem em 80×24 são rejeição automática. Prompts devem ser ASCII-puro quando possível (sem glifos Unicode exóticos em entradas de comando).
  4. Interoperabilidade Blindada → Logs binários opacos (CBOR) e saída humana (texto) e TUI rica são tratados como três vistas do mesmo receipt. Nada de “modo debug” escondido — é cidadão de primeira classe.

1.3 Soberania visual

  • Zero-Trust também é visual: nenhuma fonte externa (CDN de fontes, Google Analytics, tracker de marketing) deve vazar dados do operador. O site paebiru.org é self-hosted, sem CDN de telemetria.
  • A textura de fundo da documentação (papiro antropofágico) é asset versionado, não CDN externa.
  • Fontes canônicas (Iosevka Nerd Font) carregam via jsDelivr com fallback local documentado em docs/theme/paebiru.css.

2. Identidade Visual

2.1 Paleta de cores (Papiro Antropofágico)

A paleta é biológica-semântica: cada cor carrega um significado operacional, não é decorativa. Reutilize-a em CLI (256-color / 24-bit truecolor), TUI (ratatui), dashboards (Grafana) e site (CSS).

TokenHexRGBSignificado operacional
--membrana#1A6F5C26, 111, 92Verde-tucano profundo. Membrana saudável — barreira Bounded Context íntegra, nó conectado à malha.
--correnteza#3FA79663, 167, 150Verde-água claro. Fluxo de CausalBlock na Correnteza (WAL, Prolly Tree). Movimento contínuo, sem atrito.
--algedonia-dor#C0392B192, 57, 43Vermelho-terra. Sinal de dor algedônica: XDP saturado, temperatura alta, saturação de memória, PoW falho.
--algedonia-prazer#D4A017212, 160, 23Dourado-mel. Sinal de prazer algedônico: receipt validado, lote liquidado, peer autenticado.
--manguezal#5D4E8F93, 78, 143Roxo-cripta. Quarentena / MacrophageVM — pacote suspeito em análise, dado em apoptose.
--oceano#1B3A5C27, 58, 92Azul-profundeza. Cold storage / Oceano — dado em Maturidade Causal alta, $\Delta C \to 0$.
--nascente#E8F4F0232, 244, 240Verde-claro quase branco. Nascente / ingestão hot-path — dado chegando, ainda em ring buffer.
--ceu#F4F1E8244, 241, 232Off-white papiro. Fundo canônico da documentação e do background do CLI em modo claro.
--tinta#2B2A2843, 42, 40Carvão. Texto primário sobre --ceu. Nunca use #000 puro.
--sombra#8C8478140, 132, 120Argila. Texto secundário / bordas / divisores sobre --ceu.

Convenção de uso: use uma cor algedônica por tela. Misturar --algedonia-dor e --algedonia-prazer no mesmo componente é sintoma de falsa dicotomia — o operador precisa saber se está saudável ou não, não ambos ao mesmo tempo.

2.2 Tipografia

CamadaFonte canônicaPor quê
Mono (código, CLI, logs)Iosevka Nerd Font Extended (Light 300, Regular 400, Medium 500)Largura expandida, glifos Nerd Font para ícones inline, distingue 0/O e 1/l/I sem ambiguidade. Carrega via docs/theme/paebiru.css.
Sans (UI de documentação)Open Sans (fallback da Iosevka no site)Legibilidade em parágrafos longos. Iosevka no peso 300 (Light) assume o papel de corpo no site.
Display (capas, slides, wallpaper)Iosevka Slab ou tipografia serifada antropofágica customizadaPara títulos de capítulo, capas de RFCs, wallpaper. Sob licença compatível com AGPL-3.0.

Regras:

  • Tamanho base: 16 px no site (font-size: 1rem), 14 px no CLI (-C document.body.font_size=14 no helix ou similar).
  • Peso: use Regular (400) para corpo; Medium (500) para destaques; Light (300) para citações longas. Bold (700+) é proibido em texto corrido — reserve para cabeçalhos de tabela e labels de campo.
  • Glifos Nerd Font ( , , , ) só aparecem em TUI e em logs estruturados, nunca em mensagens de erro humanizadas (onde podem quebrar em terminais sem a fonte).
  • Sem itálico decorativo: itálico é reservado para termos em inglês, citations e nomes científicos (ex: Maturidade Causal).

2.3 Iconografia

Os ícones do PAEBIRU seguem três famílias com papéis fixos — não misture:

  1. Membrana (Bounded Contexts) — ícone quadrado com borda dupla representando permeabilidade seletiva. Cor base: --membrana.
  2. Fluxo (CausalBlock, plasmídeo) — seta orgânica com curvatura fractal. Cor base: --correnteza.
  3. Algedonia (sensor) — bulbo cromático com saturação variável (verde → âmbar → vermelho). Animação: pulsa 1 Hz em --correnteza, 4 Hz em --algedonia-dor.

Em ambientes onde ícones não são possíveis (TTY 80×24, terminais seriais LoRa), use glifos Unicode 24-BIT bem definidos como fallback: (membrana), (fluxo), (algedonia-dor), (algedonia-prazer), (manguezal), (oceano), (nascente). Veja tabela em §4.

2.4 Logomarca

A logomarca canônica é paebiru-logo-1024.png. Respeite a zona de respiro mínima de 1× a altura do glifo “p” ao redor. Não distorça proporções, não troque cores, não sobreponha fundos de baixo contraste. Para variantes em theme-color HTML (<meta name="theme-color">), use #ffffff no modo claro e #1a1c22 no modo escuro (já configurado em docs/theme/index.hbs).


3. Tom de Voz & Linguagem

3.1 Princípios editoriais

A voz do PAEBIRU é técnica, calorosa e direta. Cada palavra deve servir a um dos três objetivos:

  1. Orientar o operador na próxima ação concreta.
  2. Contextualizar a mensagem dentro da metáfora biológica.
  3. Honrar o vocabulário do Dicionário.
❌ Evite✅ Prefira
Jargão genérico (“erro interno”, “falha”)Nome do componente + causa + caminho de remediação (link ao runbook).
Hedging (“talvez”, “pode ser que”)Estado observável: “XDP saturado em 92 %” (não “talvez a rede esteja ruim”).
Pessoa em 3ª pessoa (“o usuário deve…”)2ª pessoa ou voz passiva: “Execute paebiru peer list” / “Espera-se receipt em ≤ 200 ms”.
Emoji decorativo em logsEmoji só em mensagens humanizadas (CLI interativa, docs) — nunca em logs estruturados.
Tom apologético (“desculpe”, “infelizmente”)Reconheça o estado e siga em frente: “Receipt mal-assinado; pacote descartado.”

3.2 Vocabulário canônico (pt-BR)

Use sempre a forma canônica do Dicionário. Em caso de dúvida, a forma errada vira anti-padrão:

❌ Forma proscrita✅ Forma canônica (dictionary.md)
“blockchain” / “block chain”Não use — PAEBIRU é protocolo-cérebro, não blockchain.
“consenso”“governança” / “Maturidade Causal” / “DVV”, conforme contexto.
“minerador” / “validador”“agente ABAPORU” / “nó”, conforme contexto.
“smart contract”“plasmídeo” (DSL → WASM).
“transação”“recibo” / “receipt soberano” / “interação” (DRE).
“Island mode” / “modo ilha inglês”“Modo Ilha” / “Ilha de autonomia” (nunca o inglês em pt-BR).
“consensus” misturado com texto pt“consenso” em pt-BR (ou troque pelo termo canônico).
Termo genérico “rede”“malha” (mesh). “rede” só se for rede neural/biológica.
“tempo real” / “real-time”“Maturidade Causal” / “tempo Langevin” / “tempo causal” — NUNCA “tempo real” no sentido cronológico.

3.3 Estrutura de mensagens de erro

Toda mensagem de erro em qualquer superfície (CLI, TUI, API, log) deve seguir a tríade Causa → Consequência → Caminho:

[COMPONENTE] <causa observável em uma linha>.
↳ Consequência: <o que o sistema fez em resposta>.
↳ Caminho:      <próxima ação ou link ao runbook>.

Exemplo bom (TUI do paebiru-node):

[KERNEL]  Backpressure no GossipSub fanout (fila: 9 124 / 8 192).
↳ Consequência: Publicação de plasmídeo enfileirada; receipt atrasado ~3 s.
↳ Caminho:      R007 · Saturação XDP — `paebiru peer prune --stale 30m`.

Exemplo ruim:

Erro: algo deu errado. Tente novamente.

3.4 Mensagens de sucesso

Sucesso também comunica. Use a forma <verbo no particípio> + receipt>:

[CAPIBA]  CausalBlock `b3:9f…2a` indexado no Manguezal.
           Receipt: dr://2026-06-07T11:42Z#7c1f   maturidade=4   µJ=12.4

O receipt sempre carrega: URI do DRE, maturidade causal (numérica inteira ≥ 0), e custo no LandauerLedger (µJ).


4. CLI & TUI

4.1 Estrutura de comando

A paebiru-cli (Forge CLI, em apps/cli) usa clap e segue a convenção <verbo> <substantivo> [--flags].

Regras:

  • Verbos canônicos (use exatamente estes): init, start, stop, status, list, show, add, remove, prune, rotate, quench (Veto Algedônico explícito), migrate (Oceano), flash (HAL).
  • Substantivos canônicos: node, peer, plasmid, receipt, ledger, block, key, attestation, quarantine, mesh.
  • Sub-comandos aninhados apenas quando o substantivo tem ciclo de vida próprio: paebiru plasmid build, paebiru plasmid test, paebiru plasmid publish.

4.2 Saída padrão (stdout)

  • Modo --human (default em TTY, off em pipe): cores, tabelas ASCII, spinner durante ingestão.
  • Modo --json (default em pipe/CI): uma linha JSON por evento, esquema em crates/api/....
  • Modo --cbor (interop binária): receptor de stream opaco para outros nós. Veja WASI-PAEBIRU ABI.
  • Sem --quiet/--verbose binários: use --log-level trace|debug|info|warn|error alinhado com RUST_LOG.

4.3 Códigos de saída

CódigoSignificadoCategoria
0Sucesso. Receipt emitido quando aplicável.OK
1Erro genérico do operador (argumento inválido, permissão negada).Usage
2Erro de configuração (PAEBIRU_* ausente ou inválida).Config
3Porta/endpoint em uso.Network
4Receipt mal-assinado, plasmídeo em quarentena.Security
5Veto Algedônico disparado — saúde do nó comprometida.Algedonic
6Falha de Maturidade Causal (DVV não convergiu em janela Langevin).Causal
64Erro de E/S inesperado.System
65Bug interno do PAEBIRU (reporte em paebiru/paebiru com paebiru bug-report).Internal

Convenção: códigos 1-6 são reservados a causas semanticamente distintas (se uma operação pode falhar por mais de uma razão, o operador precisa de qual é qual). Códigos 64+ seguem o padrão <sysexits.h>.

4.4 TUI (ratatui)

A TUI do paebiru dashboard (apps/cli) ocupa o terminal inteiro em modo claro/escuro. Princípios:

  • 3 painéis fixos + 1 barra de status algedônica:
    • Esquerda: topologia de malha (nós + arestas, cores por saúde).
    • Centro: fila de plasmídeos + receipts em trânsito.
    • Direita: telemetria do nó local (CPU, memória, termostato, XDP).
    • Rodapé: barra algedônica global (verde → âmbar → vermelho).
  • Navegação: tab/shift+tab cicla painéis; q quita; ? mostra ajuda; r força refresh; j/k rolam listas.
  • Frescor mínimo: 1 Hz (modo fino) ou 0.1 Hz (modo grosso), controlado por PAEBIRU_LAYER9_FINE_RESOLUTION_MS / PAEBIRU_LAYER9_COARSE_RESOLUTION_MS.
  • TTY 80×24 é o piso absoluto: degrade para paebiru status --human se a TUI não couber.

4.5 Fallback de glifos

Quando a fonte Nerd Font não está disponível, sempre degrade para glifos Unicode 24-BIT imprimíveis em qualquer encoding moderno:

ConceitoGlifo Nerd FontGlifo Unicode fallback
Membrana``
Fluxo (correnteza)``
Algedonia-dor``
Algedonia-prazer``
Manguezal (quarentena)``
Oceano``
Nascente``
Plasmídeo``
Receipt (soberano)``
Veto Algedônico``

A ordem das colunas é vinculante: documento e CLI usam o mesmo glifo para o mesmo conceito.


5. Observabilidade & Dashboards

5.1 Métricas Prometheus (canônicas)

Nome canônicoTipoUnidadeLabels obrigatórios
paebiru_kernel_pow_nonces_totalcounter1outcome (accept/reject)
paebiru_xdp_packets_dropped_totalcounter1reason
paebiru_capiba_block_maturitygauge1stage (nascente/correnteza/…)
paebiru_landauer_ledger_micro_joulescounterµJgate (1-5)
paebiru_algedonic_signalgauge1scale (1-7)
paebiru_mesh_peersgauge1state (healthy/degraded/quarantine)
paebiru_dvv_convergence_secondshistograms

Regras:

  • Unidades SI em minúsculas (seconds, bytes, joules).
  • Sem prefixos decimais ambíguos: use micro_joules, não microjoules nem uJ (reservado a humanos).
  • Labels de baixa cardinalidade apenas. PeerID vai em log, não em label (cardinality explosion).
  • Nomes com pontos são proibidospaebiru.* em vez de paebiru...

5.2 Painéis Grafana (canônicos)

A coleção paebiru-dashboards (versionada em observability/grafana/) tem sete dashboards canônicos, um por escala fractal:

  1. Bit Físico — XDP, NIC, IRQ, jitter de relógio.
  2. Neurônio LIF — spikes/segundo por camada SNN, energy budget.
  3. Função WASM — throughput de plasmídeo, falhas de MacrophageVM.
  4. Plasmídeo — fila, latência de receipt, custo em µJ por gate.
  5. Nó ABAPORU — BDI, intenções, crenças, desejo, termostato.
  6. LocalSyncDomain — DVV, Maturidade Causal, Pororoca Causal.
  7. Malha Global — topologia, peer count, island mode, fork risk.

Cada dashboard tem uma cor de cabeçalho mapeada ao token da paleta (§2.1): Malha Global = --membrana, Plasmídeo = --correnteza, etc.

5.3 Logs estruturados

  • Formato: JSON canônico com tracing-subscriber (campos fixos abaixo).
  • Campos obrigatórios:
    • ts (ISO-8601 com Z),
    • level (trace|debug|info|warn|error),
    • target (caminho do módulo Rust),
    • node_id (BLAKE3 curto, 16 chars),
    • peer_id (opcional, mesmo formato),
    • scale (1-7, escala fractal),
    • receipt_uri (opcional, dr://…).
  • Mensagem humanizada (campo msg) deve respeitar §3.3 (tríade Causa → Consequência → Caminho).

6. Documentação

A documentação segue convenções vinculantes em contributors/writing-docs.md. Resumo das regras de UX documental:

  • Caminhos relativos sempre (./../architecture/kernel.md, nunca https://…).
  • Metadados em comentários HTML (<!-- title: ... -->), nunca YAML frontmatter (mdBook renderiza YAML como texto visível).
  • kebab-case em nomes de arquivo (exceção: rfcNNN_*.md).
  • Emoji no início do capítulo funciona como ícone de seção (🌱 chegando, 🔧 operar, 🛠️ contribuir, 📚 referência, 📜 RFCs, 🎨 visuais). Não introduza emojis novos sem atualizar o SUMMARY.md pai.
  • Tabelas têm cabeçalho repetido em thead para que o leitor de tela anuncie o contexto.
  • Imagens têm alt text descritivo; imagens puramente decorativas usam alt="".
  • Mermaid é a fonte canônica de diagramas (vide §4 de writing-docs.md).

7. Acessibilidade & i18n

7.1 Acessibilidade

  • Contraste mínimo WCAG AA (4.5:1 para corpo, 3:1 para display) para qualquer par cor-texto da paleta. A combinação --algedonia-prazer sobre --ceu é a única abaixo de AA — use-a apenas em destaques de uma palavra sobre fundo branco, nunca em corpo.
  • Modo escuro respeita prefers-color-scheme (já configurado em docs/theme/index.hbsdefault_theme = "rust").
  • Sem informação veiculada apenas por cor: a barra algedônica da TUI tem padrão textual (OK, STRESS, VETO) além da cor. Ícones algedônicos têm glifo distinto ( vs. ).
  • CLI --human aceita --no-color/NO_COLOR=1 para terminais monocromáticos (MuleNode sobre UART).

7.2 Internacionalização

A hierarquia canônica está em contributors/i18n.md. Em adição:

  • Mensagens de UI são extraídas via tr!()/format_message! no crate; chaves em inglês neutro, valores em pt-BR/en-US/es-ES.
  • Termos canônicos do Dicionário NUNCA são traduzidos literalmente — preserva-se a forma de origem (ex: “Plasmídeo” em espanhol segue sendo “Plásmido”, nunca “vector de contrato”).
  • Glifos algedônicos são universais (cores têm mapeamento documentado em cada idioma).

8. Anti-padrões de UX

Sintomas de fronteira mal colocada, análogos ao anti-padrão “Costura” do Dicionário:

❌ Anti-padrãoPor quê é rejeição automática
“Wizard” genérico sem contexto biológicoForça o usuário a aprender um metalinguagem que não reaproveita. Use a metáfora: “Semente → Plântula → Árvore” para setup.
Tooltips em JSON crudoTela densa + tooltips = decoreba. Em vez disso, gere uma página de docs ancorada (/ref/cli/plasmid-publish.md).
Mensagens de erro em stack traceExpor Rust panic ao operador final é falha de membrana — queime a membrana antes de propagar.
Cores de marca sem significadoVerde/vermelho só fazem sentido com algedonia-dor/prazer. Não use verde para “sucesso genérico”.
Loading spinner sem timeout visívelO operador precisa saber se vai esperar 50 ms ou 50 s. Mostre ETA ou marque o tempo decorrido.
Configuração em 5 formatos diferentespaebiru.toml (canônico) cobre 100 % dos casos. YAML/INI/.env só com RFC que justifique.
CLI em pt-BR com mensagens internas em inglêsToda mensagem humanizada deve estar em pt-BR (ou seguir i18n). Mistura é falha de membrana i18n.
Logs com emoji decorativoLogs são stream de máquina, não de gente. Use glifos fallback (§4.5) só se forem semanticamente codificados.
Dashboard sem scale definidoAs 7 escalas fractais são a coluna do nosso sistema de coordenadas. Sem scale, a métrica é anárquica.

9. Processo de contribuição

9.1 Checklist antes de abrir PR de UI

  • A nova cor está na paleta (§2.1)? Se não, abra uma issue em paebiru/paebiru com tag design/colors antes de mergir.
  • A nova fonte está em docs/theme/paebiru.css com fallback local?
  • O novo verbo CLI está em §4.1? Caso contrário, proponha adendo ao livro de estilo junto com o PR de código.
  • As mensagens de erro seguem a tríade Causa → Consequência → Caminho ( §3.3)?
  • O glifo algedônico (se aplicável) tem fallback Unicode (§4.5)?
  • Métricas Prometheus seguem a convenção de nomenclatura (§5.1)?
  • O componente TUI degrada em 80×24 (§4.4)?
  • O texto passa em make i18n-check e respeita o Dicionário?

9.2 Versionamento

  • Mudanças neste livro de estilo são versionadas em docs/src/brand/style-guide.md e propagadas ao AGENTS.md §1.4 quando alteram um dogma.
  • Mudanças vinculantes (paleta, glifos, códigos de saída) exigem uma RFC Standards Track nova, com referência cruzada a este documento. Mudanças editoriais (texto, exemplos) entram direto via PR com label design/editorial.

10. Veja também

⬢ Identidade Visual — Iconografia

Os ícones do PAEBIRU não são meros adornos; são sinais funcionais que comunicam o estado metabólico, a escala fractal e a integridade das membranas do sistema.

Este documento detalha o uso de ícones, glifos e símbolos no ecossistema PAEBIRU, expandindo as diretrizes do Livro de Estilo.


1. Famílias de Ícones

A iconografia é dividida em três famílias funcionais. Cada uma possui uma geometria e um comportamento cromático específico, derivado da paleta Papiro Antropofágico.

1.1 Membrana (Bounded Contexts)

Representa as fronteiras de isolamento hexagonal e a permeabilidade seletiva.

  • Geometria: Quadrado ou hexágono com borda dupla.
  • Cor: --membrana (#1A6F5C).
  • Uso: Identificação de crates, módulos core e limites de domínio.

1.2 Fluxo (CausalBlock, Plasmídeo)

Representa o movimento de informação e valor através da malha.

  • Geometria: Seta orgânica com curvatura fractal ou espiral.
  • Cor: --correnteza (#3FA796).
  • Uso: Transmissão de mensagens, execução de plasmídeos e sincronização de dados.

1.3 Algedonia (Sensores de Dor/Prazer)

Representa a saúde do sistema e o feedback homeostático.

  • Geometria: Bulbo cromático ou círculo pulsante.
  • Comportamento:
    • Saudável: Cor --algedonia-prazer (#D4A017), pulso lento (1 Hz).
    • Crítico/Dor: Cor --algedonia-dor (#C0392B), pulso rápido (4 Hz).
  • Uso: Dashboards, status de nós e alertas de segurança (Veto Algedônico).

2. Glifos e Tipografia

Para interfaces de texto (CLI, TUI) e logs, utilizamos glifos da Iosevka Nerd Font.

2.1 Mapeamento Canônico

ConceitoNerd Font (Hex)Fallback UnicodeSignificado
Membrana\ueb12Limite de Bounded Context
Fluxo (Correnteza)\uf0c1Fluxo de dados/CausalBlock
Algedonia-dor\uf071Alerta crítico / Saturação
Algedonia-prazer\uf00cOperação nominal / Sucesso
Manguezal\uf06aQuarentena / MacrophageVM
Oceano\uf1b3Persistência Causal alta
Nascente\uf043Ingestão hot-path
Plasmídeo\ue22bContrato WASM
Receipt (Soberano)\uf02dProva de interação
Veto Algedônico\uf05eInterrupção por hardware

3. Logomarca

A logomarca está disponível em diversos tamanhos no diretório docs/src/brand/icons/.

3.1 Variantes

  • 1024px: Master para impressos e alta resolução.
  • 256px / 512px: Dashboards e documentação.
  • 16px / 32px / 64px: Favicons e ícones de aplicação.

3.2 Regras de Aplicação

  1. Zona de Respiro: Mantenha um espaço livre ao redor da logo equivalente a 1x a altura do glifo central.
  2. Contraste: Utilize a variante escura sobre fundos claros (--ceu) e a variante clara sobre fundos escuros.
  3. Distorção: Nunca altere a proporção ou as cores originais da logo.

4. Fallback e Acessibilidade

Sempre que a interface não suportar glifos Nerd Font ou cores TrueColor:

  • Modo TTY/Serial: Use a coluna Fallback Unicode da tabela acima.
  • Acessibilidade: Não utilize apenas cores para transmitir estado. Combine o glifo específico com a cor (ex: Vermelho + para erro).
  • Contraste: Verifique o contraste WCAG AA entre o ícone e o fundo.

5. Como Adicionar Novos Ícones

  1. Defina a Função: O ícone pertence a uma das três famílias (§1)?
  2. Escolha o Glifo: Selecione um glifo Nerd Font que não conflite com os existentes.
  3. Documente o Fallback: Todo novo ícone DEVE ter um correspondente Unicode padrão.
  4. Atualize este Documento: Adicione a nova entrada na tabela de mapeamento (§2.1).

Veja também

🎨 Identidade Visual — Wallpapers

A membrana estética do PAEBIRU: imagens que respiram a metáfora biológica e a textura antropofágica do projeto. Use-as em slides, posts, capas de relatório e na home de ambientes de campo.

Os wallpapers são ativos de marca versionados em docs/src/brand/wallpapers/ (fonte canônica) e reproduzidos nesta página para curadoria visual. Ao adicionar uma nova imagem:

  1. Coloque o arquivo em docs/src/brand/wallpapers/ em kebab-case (ex: paebiru-aurora-boreal.jpg).
  2. Atualize o catálogo abaixo com nome, dimensões, formato e intenção simbólica.
  3. Não coloque wallpapers em docs/theme/ — esse diretório é reservado a assets do template HTML/CSS (favicon, fontes, CSS customizado). Conteúdo de documentação vive em docs/src/, sob a mesma raiz do SUMMARY.md.

1. Mandala PAEBIRU

Arquivo: paebiru-dark.png Dimensões: 4096 × 2160 px (16:9, wallpaper UHD) Formato: PNG com canal alfa (RGBA, 8-bit)

Mandala PAEBIRU — wallpaper oficial

Uma composição simétrica e minimalista focada em energia e luz. Uma esfera perfeita de vidro ou cristal flutua exatamente no meio da imagem, contendo o contorno sutil e colorido dos continentes do mapa-múndi. O fundo é composto por ondulações concêntricas borradas em tons de preto e cinza escuro, imitando o efeito visual de uma gota d’água caindo em uma superfície líquida.

A mandala sintetiza os sete princípios do Manifesto em uma única imagem:

  • Auto-similaridade fractal — anéis concêntricos no fundo ecoam a iteração ingerir → metabolizar → excretar nas sete escalas (Realidade fractal).
  • Restrição antropofágica — a forma circular absorve e devora as suas próprias instâncias, sem Hierarquia externa.
  • Sensor algedônico visível — no centro exato do orbe, há uma fonte de luz branca brilhante de onde irradia uma espiral perfeita feita de pequenas formas geométricas que parecem gemas ou cristais facetados, seguindo a ordem de cores do arco-íris (espectro dos chakras): a cor vibra quando a malha está saudável e desbota para tons frios sob estresse.

Uso sugerido: capa de README, slide de abertura de talks, splash screen do paebiru-node quando o nó entra em modo Island.


2. Nautilus Holográfico

Arquivo: paebiru-mandala.png Dimensões: 4096 × 2160 px (16:9, wallpaper UHD) Formato: PNG com canal alfa

Nautilus Holográfico — wallpaper noturno

A espiral holográfica é a câmara de incubação visual do PAEBIRU — uma estrutura que lembra um chifre retorcido, uma onda ou uma criatura marinha estilizada que se curva para cima e termina em uma extremidade esférica no lado direito. O corpo dessa estrutura é revestido por linhas concêntricas e onduladas altamente saturadas em tons psicodélicos de verde-limão, rosa-choque, azul-elétrico e roxo, criando um efeito que lembra topografia digital ou óleo sobre a água.

  • Auto-similaridade fractal materializada — cada câmara da espiral é uma instância menor do todo; o giro do nautilus ecoa a iteração ingerir → metabolizar → excretar em níveis encaixados (Realidade fractal).
  • Membrana vítrea = Dogma 1 (Isolamento Hexagonal) — a estrutura funciona como uma membrana permeável entre Bounded Contexts: cada câmara é um contexto, cada septo é um port trait, e a luz que atravessa o vidro é a troca de mensagens assíncrona.
  • Núcleo branco = Kernel — a extremidade direita se assemelha a uma lente ou bola de cristal translúcida. Dentro dela, há um vórtice em espiral brilhante com as cores do arco-íris que convergem para um centro de luz branca intensa, representando o paebiru-kernel irradiando causalidade.
  • Filamentos cromáticos = receipts pós-quânticos — as linhas concêntricas e onduladas lembram as fibras nervosas da SNN neuromórfica e os rastros do LandauerLedger: cada filamento é um receipt verificável atravessando a membrana.
  • Espectro visível = os 5 Portões do ZeroTrustPipeline — as cores psicodélicas (verde-limão ao roxo) atravessam toda a pilha de segurança: filtragem volumétrica → PoW → assinatura pós-quântica → ZK-PoL → semântica de contrato.
  • Algedonia cromática — em estado saudável, o gradiente é saturado e o núcleo pulsa em luz branca; sob estresse algedônico, o espectro dessatura — espelhando a algedonia local das 7 escalas.

Uso sugerido: splash screen do paebiru-node em modo Island (alternativa vibrante à Mandala), capa de relatórios técnicos, header de dashboards, slide de abertura de talks.


3. Papiro Antropofágico

Arquivo: paebiru-papiro.jpg Dimensões: 2816 × 1536 px Formato: JPEG, 300 DPI

Papiro PAEBIRU — wallpaper alternativo

Uma ilustração complexa, repleta de misticismo, que evoca temas de conexão universal, espiritualidade e astronomia. No centro inferior, há uma representação do planeta Terra (onde se distinguem as Américas). Do centro do planeta, nasce um vórtice que se conecta a uma estrutura ramificada acima, semelhante a uma “Árvore da Vida” ou diagrama esotérico, culminando em várias esferas menores alinhadas em arco.

  • Conexão Universal — a cena central está envolta em uma grande cúpula circular, representando a malha global do PAEBIRU.
  • Fluxo de Dados — da base da Terra, uma estrada ou rio sinuoso de cores flui para fora da imagem, simbolizando o tráfego de mensagens e o metabolismo da informação.
  • Oceano Entrópico — o fundo retrata o espaço sideral de forma caótica e artística, repleto de galáxias espirais, nebulosas e planetas flutuantes, onde a maturidade causal emerge.
  • Estética Antropofágica — a imagem possui uma estética “estourada” e de alto contraste, com linhas pretas marcantes e um esquema de cores neon vibrantes (amarelo, ciano, rosa e verde) sobre um fundo predominantemente branco e brilhante, evocando a digestão de protocolos externos.

Uso sugerido: background de páginas internas, capa de whitepaper, postmortem visual.


4. Diretrizes de uso

OndePode usar?Observação
Documentação do projeto (docs/, READMEs)Atribuir a © PAEBIRU Contributors quando republicado integralmente.
Apresentações e talks sobre o PAEBIRUManter a marca d’água visível em mídias impressas.
Produtos derivados (camisetas, hardware enclosure)⚠️Requer licença explícita — abra uma issue em paebiru/paebiru com mockup.
Conteúdo comercial de terceirosA licença é AGPL-3.0-or-later; o uso comercial sem consentimento viola §5 e §13.
Treinamento de modelos de IASob política de Soberania por Design — arte do PAEBIRU não é dataset aberto.

5. Como contribuir com novos wallpapers

  1. Crie o arquivo em docs/src/brand/wallpapers/ seguindo o padrão paebiru-<tema-curto>.<ext> (kebab-case, sem espaços, sem acentos).
  2. Use resolução mínima de 1920 × 1080; idealmente 4K.
  3. Prefira PNG (com alfa) para composições com transparência e JPEG (q ≥ 90) para texturas fotográficas.
  4. Documente no AGENTS.md se o wallpaper introduzir um novo símbolo arquitetural (ex: uma representação visual de Maturidade Causal).
  5. Atualize este catálogo com nome, dimensões, formato, intenção simbólica e usos sugeridos.

A consistência estética é parte do Dogma 1 (Isolamento Absoluto): até a arte precisa atravessar a membrana hexagonal via receipt — isto é, por versionamento, atribuição e rastreabilidade.


Veja também