🌿 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.
| Passo | O que ler | O que fazer |
|---|---|---|
| 1 | Manifesto | Entenda a visão: por que outra plataforma P2P? |
| 2 | Roadmap | Saiba em que fase estamos (Fase 1 — Fundação da Névoa) |
| 3 | Setup inicial | Instale o toolchain (Nix recomendado) |
| 4 | Primeiros passos | Suba um nó, escreva um plasmídeo, converse com a malha |
Glossário essencial — malha, 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.
| Necessidade | Vá direto para |
|---|---|
| O nó não sobe | R001 · Boot de nó em campo |
| Identidade / TPM | R002 · Identidade TPM |
| Rotação de chaves | R003 · Rotação FROST |
| Ledger corrompido | R004 · Recuperação de ledger |
| Pacote suspeito | R005 · Quarentena MacrophageVM |
| Atualização OTA | R006 · Atualização OTA |
| Tráfego DDoS | R007 · Saturação XDP |
| Drift de relógio | R008 · Langevin clock drift |
| Migrar para Oceano | R009 · Migração para Oceano |
| ZK-PoL falhou | R010 · Falha de ZK-PoL |
| Desastre total | R011 · 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.
| Etapa | Documento |
|---|---|
| Processo | RSE (Research → Strategy → Execution) |
| Contrato | 4 Dogmas Inquebráveis |
| Testes | Verificação formal TLA+/Lean 4 |
| Onde mexer | Mapeamento workspace × fase |
| Especificar | Escrevendo RFCs |
| Documentar | Escrevendo docs |
| i18n | Internacionalização |
Para entender a forma do organismo:
Para entender o porquê teórico:
🗺️ Onde encontrar o quê
| Pergunta | Resposta |
|---|---|
| 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
- Homepage: https://paebiru.org
- Repositório canônico: https://github.com/paebiru/paebiru
- Issues & RFCs: https://github.com/paebiru/paebiru/issues
- Segurança (vulnerabilidades): ver
SECURITY.mdou e-mail direto (canal privado, sem abrir issue pública)
📜 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:
- Metabolismo → backpressure 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-halcomheapless. - 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 fractal — tó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 — o como e o quando.
- Realidade fractal — a Tese 7 em detalhe.
- Fundamentos termodinâmicos — a Tese 6 em detalhe.
- Dicionário canônico — os termos que usamos.
🗺️ 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/nodeecrates/kernel. Os demais 30 crates descritos noAGENTS.mdsã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 skillpaebiru-architect.
| Marco | Status | Marco de finalização |
|---|---|---|
| Toolchain nightly + Nix flake | ✅ | flake.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 curso | 2026-06-19 |
| Edge scheduler com backpressure | ✅ | 2026-07-03 |
| Island mode | ✅ | 2026-07-10 |
Política de release: não marque seu PR como
v1a 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::Saturatedtestado comproptest. - 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
kernelenode. - Compila para
riscv32imc-unknown-none-elfethumbv7em-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
LandauerLedgerdebitando 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.0em 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.0em 2027-Q1.
| Atividade | Dono | Duração |
|---|---|---|
Code freeze (branch release/v1.0.0) | maintainer | 1 dia |
cargo audit + cargo vet + revisão de segurança | segurança | 2 dias |
| Geração de binários cross (Linux x86_64/aarch64/riscv64, macOS, Windows) | release | 1 dia |
| Publicação Docker Hub + GitHub Release + tags | release | 1 dia |
| Anúncio + post-mortem do ciclo | maintainer | 2 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) epaebiru-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 |
|---|---|
| Operador | Caderno do operador |
| Contribuidor | Mapeamento do workspace |
| Pesquisador | Fundamentos |
| Decisor / financiador | Manifesto |
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-nodeem 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.tomlna raiz fixa a versão exata do nightly. Não instale stable — o projeto usa Edition 2024 + features instáveis (no_stdem 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ável | Default | Significado |
|---|---|---|
PAEBIRU_STORAGE_PATH | ~/.paebiru | Persistência (identidade, ledger, backlog) |
PAEBIRU_API_PORT | 1975 | Porta da API HTTP/observabilidade |
PAEBIRU_SKIP_PF | false | NUNCA true em produção (desabilita portão XDP) |
PAEBIRU_SKIP_TRACER | false | NUNCA true em produção (desabilita OTel) |
PAEBIRU_SKIP_GEO_DISCOVERY | false | Pula descoberta de geolocalização (use em CI) |
PAEBIRU_SKIP_GPU_TESTS | false | Pula testes com CUDA (use em CI) |
RUST_LOG | info | Verbosity: 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
- 🌱 Primeiros passos — primeiro plasmídeo.
- 🔧 Caderno do operador — se você vai operar.
- 🛠️ Processo RSE — se você vai contribuir.
Solução de problemas
| Sintoma | Causa provável | Solução |
|---|---|---|
error: linking with 'cc' failed em macOS | Xcode CLT ausente | xcode-select --install |
couldn't find libbpf | libbpf não instalado | apt install libbpf-dev ou brew install libbpf |
toolchain 'nightly-...' is not installed | rustup não tem nightly | rustup toolchain install nightly |
permission denied em /var/run/tpm0 | TPM não presente | esperado em dev; em produção use nó com TPM 2.0 |
| Porta 1975 ocupada | Outra instância rodando | lsof -i :1975 ou mude PAEBIRU_API_PORT |
| mdBook não renderiza Mermaid | mdbook-mermaid ausente | cargo 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.
- Instale o Nix (se ainda não tiver):
curl -L https://nixos.org/nix/install | sh - Habilite Flakes (adicione ao seu
~/.config/nix/nix.conf):experimental-features = nix-command flakes - 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
libbpfnão encontrada: Certifique-se de instalarlibbpf-dev.- Erro de target: Verifique se você adicionou os targets
riscv32ethumbv7viarustup. - 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
- Sintetizar: O comando
paebiru plasmid buildconverte o TOML em um binário.wasm. - Assinar: O plasmídeo é assinado com sua identidade soberana (Portão 3).
- Injetar: Você injeta o plasmídeo no seu nó local.
- 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?
- 🛠️ Guia do Contribuidor — se quer ajudar a construir o core.
- 🔧 Caderno do Operador — se vai gerenciar infraestrutura.
- 🏛️ Arquitetura — para entender os fundamentos profundos.
🛠️ 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
| Comando | Descrição |
|---|---|
paebiru node status | Exibe o estado de saúde, peers conectados e backpressure. |
paebiru identity gen | Gera uma nova identidade soberana (enraizada em hardware se disponível). |
paebiru identity export | Exporta a chave pública/PeerID para a malha. |
paebiru flash | Ferramenta de flashing para ESP32, STM32 e RISC-V. |
paebiru dashboard | Inicia 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:
- Detecta o hardware conectado (via USB/Serial).
- Compila (se necessário) o firmware
paebiru-halpara o alvo. - 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ção | Comando |
|---|---|
| Ver métricas (Prometheus) | curl http://localhost:1975/metrics |
| Ver estado do nó via CLI | paebiru 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
- Nada se reza — tudo se mede. Antes de agir, leia o estado
real do nó (
/healthz,/metrics, logs estruturados). - Backpressure é mensagem, não erro. Se o
LandauerLedgerestá vermelho, o sistema está te avisando — não force mais carga. - Receptor-reator. Cada ação sua é um ato metabólico na malha: emite um receipt. Se o receipt não voltar, refaça.
- Mude a membrana, não o core. A maioria dos incidentes se resolve trocando adaptadores, não lógica de domínio.
Ferramentas essenciais
| Ferramenta | O que dá | Comando típico |
|---|---|---|
paebiru-cli (paebiru) | Inspeção e operação local | paebiru node status |
curl http://localhost:1975/healthz | Liveness/readiness | 200 OK = OK |
curl http://localhost:1975/metrics | Prometheus endpoint | scrape por Prometheus |
journalctl -u paebiru-node -f | Logs do serviço systemd | tail -f |
PAEBIRU_API_PORT | Trocar porta da API | setar em /etc/paebiru.env |
PAEBIRU_STORAGE_PATH | Diretório de persistência | default ~/.paebiru |
Áreas de runbook
- Runbooks — 11 incidentes canônicos
- Flashing embarcado — ESP32, STM32, RISC-V
- Observabilidade — Jaeger, Prometheus, Grafana
- Troubleshooting — sintomas × causas × ações
- Postmortems — análises de incidentes passados
Antes de pedir ajuda
Reúna:
- Versão (
paebiru --version). PAEBIRU_STORAGE_PATH(anonimizado!).- Saída de
paebiru node status. - Últimos 200 linhas de log do serviço.
- Hash do commit (
git rev-parse HEAD). - O que você mudou desde a última operação bem-sucedida.
Padrão de comunicação: abra uma issue com a tag
operator-helpe 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ável | Default | Nunca em produção |
|---|---|---|
PAEBIRU_SKIP_PF | false | true (desabilita Portão 1) |
PAEBIRU_SKIP_TRACER | false | true (desabilita OTel) |
PAEBIRU_SKIP_GEO_DISCOVERY | false | true em produção |
PAEBIRU_SKIP_GPU_TESTS | false | irrelevante 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:
espflashouesptool.py. - ARM (STM32/nRF52):
probe-rsoust-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.
- Conecte-se via Serial (115200 baud).
- O dispositivo gerará um par de chaves inicial e exibirá o
PeerID. - 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étrica | Significado |
|---|---|
paebiru_metabolic_tokens | Disponibilidade de backpressure. |
paebiru_causal_maturity_drift | Diferença temporal para a malha. |
paebiru_security_gate_drops | Pacotes bloqueados por portão. |
paebiru_energy_micro_joules_total | Gasto 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
| Sintoma | Causa Provável | Solução |
|---|---|---|
Connection reset | Firewall ou MTU incompatível. | Verifique regras XDP (R007). |
Identity not found | TPM não inicializado ou path inválido. | Verifique permissões (R002). |
Drift detected | Falta de tráfego ou partição de rede. | Force um pulso manual (R008). |
Gas exhausted | Saldo 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-nodenã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
- Verifique os logs do sistema:
journalctl -u paebiru-node -n 100 -f - Tente um início manual para ver a saída direta:
cargo run -p paebiru-node - 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
havegedou similar para garantir entropia suficiente no/dev/random.
✅ Verificação
- O comando
curl http://localhost:1975/healthzretornaOK. - 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/tpm0ouIdentity not found.
🔍 Diagnóstico
- Verifique a existência do dispositivo TPM:
ls -l /dev/tpm* - Verifique se o usuário tem permissão:
groups $USER | grep tss - 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=trueestiver setado (não recomendado para produção).
✅ Verificação
- Execute
paebiru identity status. - 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
- Verifique o estado das shares locais:
paebiru identity check-shares - 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
paebiru identity statusmostra “Shares: Healthy (3/5)”.- 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 blockouHash mismatch.
🔍 Diagnóstico
- Verifique a integridade do banco local:
paebiru capiba check --full - Verifique se há espaço em disco:
df -h $PAEBIRU_STORAGE_PATH - 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
paebiru capiba checkretorna “Integrity OK”.- 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 quarantinedouMacrophageVM: Antibody synthesized. O nó detectou uma mensagem suspeita e a isolou para análise.
🔍 Diagnóstico
- Verifique o ID do pacote isolado:
paebiru security quarantine-list - 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
paebiru security statusmostra “Quarantine: Empty”.- 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
- Verifique a versão atual:
paebiru --version - 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
- O nó sobe e
paebiru --versionmostra a nova versão. paebiru node statusindica 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 limitouSaturação do Portão 1.
🔍 Diagnóstico
- Verifique a taxa de descarte:
paebiru security metrics | grep xdp_drop_rate - 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
- A taxa de descarte (drop rate) estabiliza abaixo de 5%.
- 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
- Compare o tick local com o tick da malha:
paebiru entropy status - 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
TriggerPulsepara 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
paebiru entropy statusmostra “Sync Status: Converged”.- 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
- Verifique o uso de disco por estágio:
paebiru capiba usage - 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
- Espaço em disco na partição quente é liberado.
- 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
- Verifique o backend de ZK:
paebiru security status --gate 4 - 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
- O comando
paebiru security test-polretorna “Proof valid”. - 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
HardwarePassportou 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
- O novo nó é reconhecido pela malha como o sucessor legítimo do nó anterior.
- O
LandauerLedgerreflete 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-developeroperacionaliza 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:
- Cite a fonte do problema. Issue? Runbook? RFC em
DRAFT/PROPOSED? Bug? Postmortem? Sem fonte, a tarefa não é contribuição — é feature creep. - 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. - Verifique o Dicionário canônico
reference/dictionary.mdpara termos relevantes. Se um termo não estiver, adicione-o antes de propor código. - Leia a skill relevante em
.agents/skills/— oupaebiru-architectse for transversal. - 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:
- 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-helpantes de prosseguir. - 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). - 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_stdse tocar Kernel/Math.
- 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_stdbuild)?
- 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:
- Branches pequenos. Um branch por unidade lógica:
feat/<bc>-<unidade>,fix/<bc>-<sintoma>,docs/<escopo>,rfc/<número>-<slug>. - Commits atômicos. Um commit por mudança conceitual. Mensagem em imperativo, assunto ≤ 72 chars, corpo que responde por quê (não o quê).
- 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 - 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).
- 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::Instantno 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 RFC | Abra 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
- Verificação formal
- Mapeamento do workspace
- Escrevendo RFCs
- CONTRIBUTING.md §3 (RSE)
- Skill
paebiru-developer
🛡️ 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
mainsem 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 deactor/,ports/ouadapters/. 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::Instantemdomain/.tokio::spawnoumpsc::channelemdomain/.- 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
structdo ator; nada deMutex<DomainState>. - Mensagens entre BCs são serializáveis (
Serialize + Deserialize).
Sinais de violação:
std::sync::Mutex,std::sync::RwLockno domínio ou no ator.thread::sleep,std::thread::joinem código de runtime.- Operações de I/O síncronas (
std::fs::read,std::net::TcpStream) sem wrapperasync.
⚙️ 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 parariscv32imc-unknown-none-elfethumbv7em-none-eabihfsem warnings.crates/math/compila para os mesmos alvos.- Coleções dinâmicas usam
heaplessem vez deVec/HashMapno caminho embarcado.
Sinais de violação:
use std::collections::*em códigodomain/.- Alocação dinâmica (
Box,Vec,String) em códigono_std. - Dependências que exigem
stdautomaticamente.
🔌 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/protobufproibidos emcrates/bindings/*para caminhos quentes.
Sinais de violação:
- Tipos Rust complexos visíveis no header C.
serde_json::from_strem 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:
| Ferramenta | O que verifica | Bloqueia? |
|---|---|---|
cargo fmt --all -- --check | Formatação canônica | Sim |
cargo clippy --all -- -D warnings | Lints oficiais | Sim |
cargo audit | CVEs em dependências | Sim (HIGH/CRITICAL) |
cargo vet | Supply chain (lockfile de imports) | Sim |
rtk make lint (via rtk proxy) | Igual a make lint mas rápido | Sim |
pre-commit (.pre-commit-config.yaml) | Whitespace, EOF, YAML, TOML | Sim |
Saída da esteira: zero erros, zero warnings de clippy, zero CVEs HIGH/CRITICAL.
Esteira 2 — GALS & Domínio (testes + cobertura)
Ferramentas:
| Ferramenta | O que verifica | Bloqueia? |
|---|---|---|
cargo test --all | Suíte unitária + integração | Sim |
cargo test --doc | Doctests | Sim |
cargo llvm-cov --all --fail-under-lines 90 | Cobertura de linhas ≥ 90 % | Sim |
proptest (em crates relevantes) | Invariantes por property-based | Sim em Kernel/crypto/economia |
cargo test --test local_node_integration | Ciclo de vida ponta-a-ponta | Sim |
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:
| Ferramenta | Onde | O que prova |
|---|---|---|
| TLA+ | crates/*/formal/tla/ | Concorrência, GALS liveness, soma zero de crédito, soundness de ZK-PoL |
| Lean 4 | crates/paebiru-math/formal/lean/ e formal/lean/ | Pureza algorítmica: Haversine, Reed-Solomon, Ising, Langevin, MutualCredit |
make verify-formal | orquestrador | Roda 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:
| Alvo | Comando | Aplicável a |
|---|---|---|
riscv32imc-unknown-none-elf | cargo check --target riscv32imc-unknown-none-elf | Kernel, Math, HAL |
thumbv7em-none-eabihf | cargo check --target thumbv7em-none-eabihf | Kernel, Math, HAL |
wasm32-unknown-unknown | cargo check --target wasm32-unknown-unknown --no-default-features | Plasmids, Kernel (subset) |
Saída da esteira: build limpo para todos os alvos embarcados suportados pela mudança.
Tabela de mapeamento: dogma × esteira
| Dogma | Esteira 1 (Conform.) | Esteira 2 (GALS) | Esteira 3 (Formal) | Esteira 4 (Embarcada) |
|---|---|---|---|---|
| 1. Hexagonal | clippy lints sobre imports | Testes de porta mockada | TLA+ sobre membrana | no_std build |
| 2. GALS & Ator | Lints clippy::async_yields_async | Teste do loop do ator | TLA+ liveness | no_std + heapless |
3. no_std | cargo check --no-default-features | Suíte no_std-only | Lean 4 sobre funções puras | Toda a esteira |
| 4. Opaque FFI | cargo clippy + revisão manual | Testes de binding | — | Compila 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-architectantes de propor patches que tocam dogmas. Cite o dogma preservado no PR.
Veja também
- AGENTS.md §4 — Convenções de código
- Processo RSE
- Verificação formal
- CONTRIBUTING.md §2 — Princípios inegociáveis
- Dicionário · Maturidade Causal
🛡️ 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.
| Ferramenta | Uso Principal | Localização |
|---|---|---|
| TLA+ | Concorrência, loop GALS, liveness de atores, consenso bizantino. | crates/*/formal/tla/ |
| Lean 4 | Pureza 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 buildno 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.
- Research: Identificar as propriedades de segurança e liveness.
- Strategy: Escrever o modelo TLA+ ou Lean.
- 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)
| Crate | Bounded Context | Estado | Responsabilidade |
|---|---|---|---|
paebiru-kernel | Kernel | 🟢 Estável | Loop GALS, Rede, Segurança |
paebiru-node | (App) | 🟢 Estável | Daemon principal do nó |
paebiru-math | Matemática | 🟡 Beta | Ising, Langevin, Reed-Solomon |
paebiru-biology | Biologia | 🟠 Alfa | ABAPORU, SNN |
paebiru-economy | Economia | 🟠 Alfa | DRE, Barter, Joule |
paebiru-capiba | C.A.P.I.B.A. | 🟠 Alfa | Persistência Causal |
paebiru-hal | HAL | 🟠 Alfa | no_std, Drivers |
paebiru-api | API | 🟠 Alfa | HTTP, Metrics, Tracing |
3. Fluxo de Dependências
Para preservar o Dogma 1 (Isolamento Hexagonal), seguimos uma hierarquia estrita:
paebiru-mathepaebiru-commonssão a base (zero dependências internas).paebiru-kerneldepende da base.- Bounded Contexts de domínio (
biology,economy,learn) dependem dokernelatravés de traits. paebiru-nodeorquestra 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
- Roadmap — Visão temporal da maturidade.
- Qualidade · Dogma 1
- AGENTS.md — Lista técnica completa de crates.
📜 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 (
traitemcrates/*/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)
- Idea: Discuta a ideia em uma Issue ou Discussion com a tag
rfc-proposal. - Draft: Solicite um número (ex: RFC 054) e copie o template oficial.
- Proposed: Abra um PR com o status
PROPOSED. O PR deve ficar aberto por pelo menos 14 dias para debate técnico. - Standard: Se houver consenso, um mantenedor marca como
STANDARDe 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
supersedesno 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
.mdusamkebab-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
- pt-BR: Idioma da documentação de core, RFCs e comentários de código.
- en-US: Idioma para visibilidade internacional e SDKs.
- 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:
- Crie uma pasta com o código do idioma (ex:
docs/src/en/). - Mantenha a estrutura de arquivos idêntica à de
docs/src/. - Utilize o comando
make i18n-checkpara 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:
- Bit Físico: A unidade mínima de custo termodinâmico.
- Neurônio LIF: A unidade de processamento neuromórfico (SNN).
- Função WASM: A unidade lógica dentro de um plasmídeo.
- Plasmídeo: A unidade de governança e contrato.
- Nó ABAPORU: A unidade de soberania individual.
- LocalSyncDomain: O cluster local de alta confiança (Fog).
- 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:
- Ingestão: Recebimento de mensagens e estímulos (spikes).
- Digestão: Processamento via loop GALS e execução de plasmídeos.
- 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 deactor/,ports/ouadapters/. A seta vai doactorpara odomain— 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ódulo | Camada hexagonal | Responsabilidade |
|---|---|---|
domain/ | Núcleo | Lógica pura: tracking de peers, backpressure, decisão metabólica |
ports/ | Portas | Traits assíncronos que o domínio “vê” do mundo |
actor/ | Aplicação | Loop GALS que conecta domínio a portas |
adapters/ | Adaptadores | Implementaçõ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:
| Constante | Valor | Significado |
|---|---|---|
MAX_TOKENS | 100.0 | Capacidade máxima do bucket |
REFILL_RATE_PER_MS | 0.1 | 100 tokens / segundo |
Algoritmo:
- Em cada
handle_message, primeiro reabastece o bucket proporcional anow_ms - last_refill_ms. - Se
tokens < 1.0, retornaMetabolicAction::Saturated(sem consumir). - Senão, consome 1 token e processa a mensagem.
- Para
PulseRequest: registra/atualiza oPeerHealthdo emissor e agendaPulseResponse. - Para
PulseResponse: atualiza ohealth_scoredo 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 mesmaMetabolicAction. Isso é verificável porproptest.
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 é
asynceawaitada; ompsc::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á
MutexnoMetabolism— a imutabilidade estrutural doactoré 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 teste | Onde | O que cobre |
|---|---|---|
Unitário (#[test]) | crates/kernel/src/domain/tests | Metabolism puro — proptest! sobre (sender, msg, now) |
| Integração | crates/kernel/tests/actor_loop.rs | KernelActor::run com NetworkPort mockado |
| Property-based | crates/kernel/proptest-recipes | Invariante: tokens ∈ [0, MAX_TOKENS] |
| no_std | cargo check --target riscv32imc-unknown-none-elf | domain/ compila sem std |
Cobertura-alvo: ≥ 90 % (enforçada por make coverage).
8. O que não é Kernel
- Persistência →
capiba.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
- Dicionário · GALS
- Dicionário · Maturidade Causal
- Dicionário · Sensor algedônico
- Capiba · Memória persistente (o BC vizinho que consome receipts do Kernel)
- Quatro Dogmas Inquebráveis
- Glossário da skill
paebiru-architect
🌿 Biologia — O Organismo
O Bounded Context de Biologia implementa a camada cognitiva e metabólica do PAEBIRU. Enquanto o
kernelcuida da sobrevivência mecânica (rede, mensagens), abiologiacuida 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
MetabolicActiondo Kernel é o sinal de “fome” ou “saciedade” do sistema.
4. Invariantes do Domínio
- Soberania Decisória: O ABAPORU local sempre tem a palavra final sobre o uso de seus recursos.
- Prioridade Termodinâmica: A sobrevivência física do nó (homeostasia) precede qualquer objetivo da malha.
- 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
ZeroTrustPipelinetem 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
- Soma Zero: O balanço global de créditos e débitos deve ser sempre zero.
- Materialidade: Todo crédito deve ser lastreado em contribuição real de recurso (energia/computação/dado).
- Privacidade: As transações preservam a soberania do nó; detalhes granulares são revelados apenas sob quorum.
6. Veja também
- Dicionário · DRE
- Dicionário · LandauerLedger
- Dicionário · Loteria Joule
- Teoria · Fundamentos Termodinâmicos
🌊 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
kernelcuida da mensagem em trânsito, ocapibacuida 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
| Tipo | O que é C.A.P.I.B.A. | O que não é |
|---|---|---|
| Em escopo | Persistência causal, content addressing, sincronização MuleNode, DRE (Data Refinery Engine), schema evolution (Iceberg), compute-over-data, retenção/apoptose | Transporte de mensagem em rede (→ kernel) |
| Em escopo | IPLD CIDs, BLAKE3, Prolly Trees, Apache Arrow/Parquet/Iceberg | Treinamento de modelos ML (→ learn) |
| Em escopo | Políticas MUS, Landauer Gate, Sovereignty Gate | Definição de plasmídeos (→ plasmids) |
| Em escopo | Sincronização Pororoca Causal | Decisões de governança/DAO (→ economy) |
| Em escopo | Assinatura 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
| Conceito | Tipo canônico | Função | Onde vive |
|---|---|---|---|
CausalBlock | struct { content_hash: BLAKE3, dvv: DottedVersionVector, payload: Bytes, signature: MlDsa65 } | Unidade imutável básica | capiba::domain::block |
DottedVersionVector | struct { node_id: PeerId, counter: u64 } (par) | Base de maturidade causal | capiba::domain::dvv |
ProllyTree | árvore Merkle com rolling hash | Sync delta eficiente | capiba::prolly |
IpfsCid | newtype — CID v1, multicodec, multihash BLAKE3 | Content addressing global | capiba::ipfs::cid |
MusThreshold | const por tipo de bloco | Maturidade mínima para retenção | capiba::domain::mus |
MuleReceipt | struct { origin: PeerId, batch_id, dvv_window } | Recibo de sync MuleNode | capiba::mule |
IcebergManifest | struct { schema_id, snapshot_id, partition_spec, lineage } | Schema evolution | capiba::iceberg::manifest |
QuantumReceipt | struct { block: CausalBlock, from_stage, to_stage, joules, timestamp } | Recibo de transmutação | capiba::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)
- 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. - Content addressing. Endereço é o par
(BLAKE3(conteúdo), DVV). Mesmo conteúdo em maturidades diferentes = CIDs diferentes. - Apoptose saudável.
MUSdefine a maturidade abaixo da qual o bloco evapora. Não é “limpeza” — é metabolismo. - Sovereignty Gate. Antes de Oceano, audit (CDDL + semântica + ZK-PoL se houver geolocalização).
- Compute-over-data > move-data. Compute vai até o storage.
- Quarentena imunológica. Manguezal é filtro Zero-Trust; lama
tóxica →
MacrophageVM. - Sincronização MuleNode. Pororoca Causal: batched, eventual,
com
_receipts_imutáveis. - 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ília | Latência | Consistência | Estágio | Executor típico |
|---|---|---|---|---|
| Ingestão | µs | Eventual local | Nascente | ABAPORU IoT |
| Sincronização | ms | Causal | Correnteza | MuleNode + DHT |
| Análise | s | Forte eventual | Manguezal/Oceano | Fog/Cloud node |
| Computação | min–h | Idempotente | Chuva | Edge 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]
kernel↔capiba: todo receipt soberano é persistido comoCausalBlock; toda leitura de receipt é via DVV (não por timestamp).biology↔capiba: eventos de ABAPORU (crença, desejo, intenção) viram blocos causais; memória de longo prazo do agente = Nascente + Correnteza.learn↔capiba: trainer federado (Chuva) consome Iceberg (Oceano) e emite plasmídeo (precipitação).economy↔capiba: o DRE (Data Refinery Engine) usa C.A.P.I.B.A. como insumo canônico para oLandauerLedger.zk↔capiba: 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
- Migration no DRE (
capiba::dre::migrations). - Atualizar
MusThresholdse a coluna afeta retenção. - Atualizar este documento.
- Teste de round-trip causal (escreve → lê em DVV maior → compara).
make test+ fuzzing de serialização Iceberg.
Adicionar política de apoptose (MUS)
- Invariante formal em TLA+ (
capiba/formal/). - Implementação em
capiba::domain::apoptosis. - Teste property-based com maturidades aleatórias.
- Verificar que a Landauer Gate não viola $k_B \cdot T \cdot \ln 2$.
- Métrica Prometheus:
paebiru_capiba_apoptosis_total.
Criar novo MuleNode adapter (CAN bus, Modbus)
- Implementar
capiba::ports::MuleTransport. - Adapter em
capiba::adapters::mule::<tecnologia>. - Garantir
no_stdcompatível. cargo check --target thumbv7em-none-eabihf.- 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-securityfoi consultado? - Se toca ML/inferência,
paebiru-aifoi consultado? - Testes property-based para invariantes causais?
-
cargo test -p paebiru-capiba+--target thumbv7em-none-eabihfse aplicável? - Documentação (este arquivo) atualizada?
Veja também
- Dicionário canônico · C.A.P.I.B.A.
- Skill
paebiru-data— fonte operacional - Math foundations · DVV
- Math foundations · Landauer
- Maturidade Causal · fila M/M/1
- Tópicos a formalizar — versões formais em construção
🌀 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
- Conservação de Energia: O custo de processamento deve ser sempre contabilizado no
LandauerLedger. - Irreversibilidade: Operações que modificam o estado global são tratadas como processos termodinâmicos irreversíveis.
- 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
- Dicionário · Langevin Ticks
- Dicionário · LandauerLedger
- Teoria · Fundamentos Termodinâmicos
- Referência · Matemática
🧠 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:
- O agregador consolida os pesos.
- Os novos pesos são injetados em um template de plasmídeo.
- O plasmídeo é assinado via FROST (assinaturas distribuídas).
- A nova “inteligência” é propagada pela malha.
5. Invariantes do Domínio
- Soberania do Dado: Dados brutos nunca são transmitidos.
- Resiliência Bizantina: O sistema deve convergir mesmo com uma porcentagem de nós adversariais.
- Maturidade Causal: Rounds de aprendizado são ordenados via DVV para evitar ataques de replay ou confusão temporal.
6. Veja também
- Dicionário · FedAvg
- Dicionário · Agregação Bizantina
- Teoria · Arquitetura Cognitiva
- Skill
paebiru-ai
🔌 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:
/healthze/readinesspara orquestração. - Métricas:
/metricsno 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
tracingeopentelemetrypara 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
- Segurança por Default: Nenhum endpoint de mutação de estado é exposto sem autenticação mútua (mTLS) ou prova de identidade soberana.
- Backpressure de API: Se o nó estiver saturado (metabolismo alto), a API retorna
429 Too Many Requestscom base nos tokens do Kernel. - Idempotência: Operações de mutação devem ser idempotentes através de identificadores únicos no cabeçalho da API.
5. Veja também
- Dicionário · DRE
- Dicionário · ZeroTrustPipeline
- Arquitetura · Bounded Contexts
- Referência · CLI do Forge
🌉 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.
2. Chainlink (Oráculos)
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
- Abstração de Protocolo: O Kernel não sabe que está falando com a Ethereum ou Filecoin; ele interage com
BridgePortsgenéricos. - Minimização de Confiança: Toda ponte deve incluir verificação local de provas (ex: proofs de inclusão Merkle) sempre que possível.
- 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
tracingque injetam contexto metabólico (Langevin Ticks) em todos os logs. - Profiling: Ferramentas de medição de performance
no_stdcompatíveis. - Validation: Macros para validação de invariantes em tempo de compilação e execução.
3. Invariantes do Domínio
- Minimalismo: O Commons deve ter o mínimo de dependências possível.
- Estabilidade: Por ser a base do grafo de dependências, mudanças no Commons devem ser raras e extremamente bem testadas.
- 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_stdFirst).
1. Suporte a Hardware
O PAEBIRU HAL é projetado para ser agnóstico, suportando diversas arquiteturas através de traits do embedded-hal.
| Arquitetura | Targets Exemplo | Estado |
|---|---|---|
| RISC-V | riscv32imc-unknown-none-elf | 🟢 Suportado |
| ARM Cortex-M | thumbv7em-none-eabihf | 🟢 Suportado |
| Xtensa | ESP32, ESP32-S3 | 🟡 Em testes |
| AVR | ATmega 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
heaplesspara 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
- Eficiência Estrita: Cada ciclo de clock e byte de RAM deve ser justificado (Dogma 3).
- Abstração Transparente: O domínio do HAL expõe traits genéricos para que o
kernelebiologypossam rodar o mesmo código lógico em x86 ou RISC-V. - 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-plasmidsainda não está implementado no workspace (somente okernelestá materializado emcrates/). Este arquivo existe para (a) desbloquear o build do mdBook em modo strict — oSUMMARY.mdprecisa 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
| Tipo | O que é Plasmídeos | O que não é |
|---|---|---|
| Em escopo | Sintaxe da DSL (TOML/HCL), parser, AST, compilador para WASM, assinatura pós-compilação, versionamento, empacotamento como CausalBlock | Execução do WASM em si (→ kernel + wasmtime) |
| Em escopo | Vinculação a host imports (WASI-PAEBIRU ABI), limites de recursos, contratos de dados (CDDL) | Persistência do estado do plasmídeo (→ capiba) |
| Em escopo | Catálogo de plasmídeos canônicos (transferência, validação, atestação) | Distribuição/libp2p dos plasmídeos pela malha (→ kernel) |
| Em escopo | Sandbox de teste e “playground” para autores | Política econômica de execução (→ economy) |
2. Estado atual e roadmap
- Pré-Fase 2 — projeto apenas arquitetado.
- A sintaxe-alvo está descrita em Referência · DSL de Plasmídeos.
- A interface binária está descrita em Referência · WASI-PAEBIRU ABI.
- O compilador será escrito em Rust; o backend imediato é
wat(texto WAT) →wasm-tools→wasmtime.
3. Invariantes do Domínio
- Determinismo: Um mesmo
plasmid.tomldeve produzir um mesmoplasmid.wasmbyte-a-byte (content addressing estável). - Imutabilidade pós-compilação: o plasmídeo, uma vez compilado e assinado, é um CausalBlock — não é editável, apenas substituído.
- Sandbox obrigatório: zero syscalls fora do
host importsdeclarado; owasmtimeaplica fuel e memória limitada. - Recibos Soberanos: toda execução emite um recibo DRE com referência ao CID do plasmídeo (ver Dicionário · DRE).
- Idempotência de invocação: o mesmo
(plasmid_cid, input_cid)produz o mesmo(output_cid, receipt_cid).
4. Veja também
- Referência · DSL de Plasmídeos
- Referência · WASI-PAEBIRU ABI
- Dicionário · Plasmídeo
- Arquitetura · Bounded Contexts
- ROADMAP
🔐 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-zkainda não está implementado no workspace (somente okernelestá materializado emcrates/). Este arquivo existe para (a) desbloquear o build do mdBook em modo strict — oSUMMARY.mdprecisa 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
| Tipo | O que é ZK | O que não é |
|---|---|---|
| Em escopo | Geração de chaves de prova, setup (SRS), circuit para ZK-PoL (Haversine + bounding-box), serialização de provas Groth16 | Criptografia de transporte / Noise / TLS (→ kernel) |
| Em escopo | Verificação de provas (verifier otimizado para no_std quando possível) | Assinaturas pós-quânticas ML-DSA / ML-KEM (→ kernel) |
| Em escopo | Composição de provas (rollup de várias PoL em um único recibo) | Política de quando uma PoL é exigida (→ decisão de protocolo) |
| Em escopo | Bindings 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
CausalBlockseparado assinado por AMBOS os nós.
3. Invariantes do Domínio
- Soundness acima de tudo: nenhuma prova aceita sem verificação completa do verifier; verificação parcial é proibida (anti-class: trusted setup trap).
- SRS público e verificável: a structured reference string deve ser gerada por cerimônia pública verificável; nunca SRS descartável.
- Sem replay: cada prova inclui um nonce causal derivado do DVV atual — provas velhas não são reusáveis.
- Falha visível: prova inválida → recibo com
verdict=reject- entrada no
MacrophageVMpara análise; nunca fail-silent.
- entrada no
- 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
- Referência · Matemática · Groth16
- Runbook · R010 · Falha de ZK-PoL
- Dicionário · PoL
- Dicionário · ZK-PoL
- Arquitetura · Bounded Contexts
🧠 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
| Ensaio | Pergunta que responde |
|---|---|
| Arquitetura cognitiva | Como o PAEBIRU pensa — agentes BDI, SNN, atenção |
| Protocolos de coordenação | Como agentes concordam — quorum, estigmergia, gossip |
| Fundamentos termodinâmicos | Como 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
- Se você é novato no projeto: comece por Arquitetura cognitiva.
- Se você está mexendo em consenso / partição: vá para Protocolos de coordenação.
- Se você está mexendo em scheduler / backpressure: Fundamentos termodinâmicos.
Veja também
- Dicionário canônico — termos do projeto
- Arquitetura — Bounded Contexts
- Manifesto — as 7 teses
🧠 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:
- Uma função WASM tem uma cognição primitiva de entrada/saída.
- Um plasmídeo coordena várias funções.
- Um nó coordena plasmídeos.
- 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
ReceipteCausalBlockdeixa 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.
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.
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.
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.
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.
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.
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.
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.
Convenção editorial: grafia sempre em Title Case —
Bounded ContexteBounded Contexts(plural), mesmo em meio de frase. A forma minúsculabounded 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.
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ágio | Função | Representação canônica |
|---|---|---|---|
| 1 | Nascente | Ingestão hot-path | Ring buffer / RAM lock-free |
| 2 | Correnteza | Sincronização causal | MmapStore / WAL + Prolly Trees |
| 3 | Manguezal | Quarentena + análise | Apache Arrow in-memory + filtro Zero-Trust |
| 4 | Oceano | Cold storage soberano | Apache Iceberg + IPLD CIDs (BLAKE3) |
| 5 | Chuva | Compute-over-data | Trainer federado → WeightDelta → Plasmídeo |
Princípios vinculantes (cada item é rejeição automática em revisão):
- Tempo causal, não cronológico — ordenação por DVV, jamais por
Instant::now(). - Content addressing — blocos endereçados por
(hash_conteúdo, maturidade_causal), não por path. - Apoptose saudável —
MUS(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$. - Sovereignty Gate — antes de descer para o Oceano, dados são auditados (CDDL + validação semântica + ZK-PoL se houver geolocalização).
- Compute-over-data > move-data — a Chuva (compute) vai até o Oceano (storage), não o contrário.
- Quarentena imunológica — o Manguezal é filtro Zero-Trust; “lama tóxica” vai para
MacrophageVM. - Sincronização MuleNode — MuleNodes (LoRa, ATmega) sincronizam via Pororoca Causal — batched, eventual, com receipts imutáveis.
- 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.
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.
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.
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 adjetivacreditá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.
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.
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.
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.
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.
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.
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.
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.
G
GALS (Globally Asynchronous, Locally Synchronous)
Paradigma fundamental: atores localmente síncronos, comunicação globalmente assíncrona via troca de mensagens. Dogma 2 .
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.
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.
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.
Convenção editorial: grafia canônica
Ilha de autonomiaou forma abreviadaModo Ilha(ambas aceitas). A forma inglesaIsland 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.
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.
Langevin Ticks
Unidade de tempo baseada na dinâmica de Langevin — estocástica,
termodinamicamente fundamentada. No regime v3+ é a base da
Dança Politemporal.
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.
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.
M
MacrophageVM
Sandbox WASM (rodando em wasmtime) onde pacotes suspeitos são
fagocitados e analisados em profundidade. Sintetiza anticorpos.
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.
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.
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).
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.
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.
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.
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:
- Sinal de vida (heartbeat) — emitido periodicamente (período
padrão de 10s, configurável via
DEFAULT_PULSE_PERIODemapps/node/src/lib.rs). - Atualização de saúde — cada
PulseResponsecarrega umhealth: f32 ∈ [0.0, 1.0]que alimenta oPeerHealthnoMetabolism(ver BC Kernel) e, em última instância, oAlgedonicSensorlocal. - Re-sincronização causal — em nós congelados, dispara avanço do Langevin Tick (ver R008 · Langevin Clock Drift).
- 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/PulseResponseponta-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.
PoL (Proof of Location)
Prova de localização física preservando privacidade das coordenadas exatas. Construída via zk-SNARK Groth16.
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.
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.
R
Realidade fractal
Ver Auto-similaridade 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).
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.
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.
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.
Convenção editorial: grafia sempre em Title Case —
Veto Algedônico(substantivo próprio), mesmo em meio de frase. A forma minúsculaveto 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).
Z
ZeroTrustPipeline
Cadeia de 5 portões que todo pacote deve atravessar:
- Load Shedder (eBPF/XDP)
- Proof-of-Work (BLAKE3 salt + nonce)
- Assinatura ML-DSA
- ZK-PoL (Groth16)
- Contrato de Dados (CDDL)
ZK-PoL
Ver PoL.
Apêndice — Siglas invertidas
| Sigla | Forma canônica | BC / Crate |
|---|---|---|
| ABAPORU | Agente BDI | biology |
| C.A.P.I.B.A. | Causal, Asynchronous, Persistent, Immutable Block Architecture | capiba |
| CDDL | Concise Data Definition Language | kernel |
| DRE | Distributed Receipt Engine | economy |
| DVV | Dotted Version Vector | capiba |
| eBPF | Extended Berkeley Packet Filter | kernel |
| FedAvg | Federated Averaging | learn |
| FLAIR | Federated Learning with AI-driven Rewards | learn |
| FROST | Flexible Round-Optimized Schnorr Threshold | kernel |
| GALS | Globally Asynchronous, Locally Synchronous | (transversal) |
| HAL | Hardware Abstraction Layer | hal |
| ML-DSA | Module-Lattice-Based DSA | kernel |
| ML-KEM | Module-Lattice-Based KEM | kernel |
| PoL | Proof of Location | zk |
| SNN | Spiking Neural Network | biology |
| WASI | WebAssembly System Interface | plasmids |
| XDP | eXpress Data Path | kernel |
| ZK | Zero-Knowledge | zk |
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
| Benchmark | Tempo Médio | Unidade |
|---|---|---|
actor_handle_incoming_message | 105.42 | ns |
handle_pulse_request | 25.530 | ns |
handle_pulse_response | 25.645 | ns |
handle_pulse_request_with_32_peers | 25.524 | ns |
get_current_pressure | 311.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
- Equações de Langevin
- Hamiltoniano de Ising
- Reed-Solomon sobre Corpos de Galois
- Dotted Version Vectors (DVV)
- Fórmula de Haversine
- Análise Topológica de Dados (TDA)
- Backpressure M/M/1
- Groth16 (zk-SNARKs)
- 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ímbolo | Significado |
|---|---|
| $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)$:
- Codifica em polinômio $p(x) = m_0 + m_1 x + \cdots + m_{k-1} x^{k-1}$.
- Avalia em $n$ pontos ($\mathrm{GF}(2^8)^* \cup {0}$).
- 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_stdempaebiru-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.
| Modelo | Onde vive | O que prova |
|---|---|---|
| GALS-liveness | crates/paebiru-kernel/formal/tla/gals.tla | progresso dos atores em partição |
| DRE sum-zero | crates/paebiru-economy/formal/tla/dre.tla | invariante de balanço |
| ZK-PoL soundness | crates/paebiru-zk/formal/tla/pol.tla | completude e solidez |
Haversine no_std | crates/paebiru-math/formal/lean/Haversine.lean | precisão geodésica |
| Reed-Solomon | crates/paebiru-math/formal/lean/ReedSolomon.lean | correção ≤ $\lfloor (n-k)/2 \rfloor$ |
| Ising | crates/paebiru-math/formal/lean/Ising.lean | annealing monotônico |
| Langevin | crates/paebiru-math/formal/lean/Langevin.lean | $\Delta t \propto \Delta S / \gamma$ |
| Mutual credit | formal/lean/MutualCredit.lean | soma zero contínua |
Acionada por make verify-formal.
Veja também
- Dicionário canônico — termos, não fórmulas.
- Filas M/M/1 — modelagem detalhada de filas.
- Padrões — receitas algorítmicas recorrentes.
- Verificação formal (guia de contribuidor).
📊 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ó
| Comando | Descrição |
|---|---|
paebiru node start | Inicia o daemon do nó. |
paebiru node stop | Para o nó graciosamente. |
paebiru node status | Exibe saúde, peers e backpressure. |
paebiru node peers | Lista todos os peers na vizinhança causal. |
2. Comandos de Identidade
| Comando | Descrição |
|---|---|
paebiru identity gen | Gera uma nova identidade soberana. |
paebiru identity show | Exibe o PeerID e chaves públicas. |
paebiru identity import | Importa uma identidade existente. |
paebiru identity rotate | Inicia cerimônia FROST de rotação. |
3. Comandos de Plasmídeo
| Comando | Descriçã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 list | Lista plasmídeos ativos no nó. |
4. Variáveis de Ambiente
| Variável | Padrão | Descrição |
|---|---|---|
PAEBIRU_STORAGE_PATH | ~/.paebiru | Onde os dados e identidades são salvos. |
PAEBIRU_API_PORT | 1975 | Porta do servidor HTTP de observabilidade. |
RUST_LOG | info | Ní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 paraheaplessno 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
| Binding | Crate | Tecnologia | Estabilidade |
|---|---|---|---|
| C | paebiru-c | FFI nativo | 🟢 Estável |
| Python | paebiru-py | PyO3 | 🟡 Beta |
| TypeScript/WASM | paebiru-ts | wasm-bindgen | 🟡 Beta |
| Go | paebiru-go | CGO | 🟡 Beta |
| Java | paebiru-java | JNI | 🟡 Beta |
| C# | paebiru-csharp | P/Invoke | 🟠 Alfa |
| Dart | paebiru-dart | FFI | 🟠 Alfa |
| Swift | paebiru-swift | UniFFI | 🟠 Alfa |
| Ruby | paebiru-ruby | Magnus | 🟠 Alfa |
| PHP | paebiru-php | ext-php-rs | 🟠 Alfa |
| Lua | paebiru-lua | mlua | 🟠 Alfa |
| R | paebiru-r | extendr | 🟠 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
- Design assíncrono — como o runtime tokio aparece em cada linguagem.
- Guia de release — versionamento e compatibilidade.
- Bindings individuais — um arquivo por linguagem.
Veja também
- WASI-PAEBIRU ABI — o contrato subjacente que todo binding respeita.
- Zero-Copy FFI — tópico em formalização.
- Dogma 4 · Interoperabilidade Blindada.
🌀 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
asyncou que retornamPromises/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:
- O usuário registra um handler no SDK.
- O Kernel Rust recebe a mensagem e a coloca em uma fila de despacho.
- 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ível | Significado | Exemplo |
|---|---|---|
| 🟢 Estável | API congelada, garantias de compatibilidade por 12 meses. | paebiru-c |
| 🟡 Beta | Funcional, mas APIs podem sofrer ajustes menores. | paebiru-py, paebiru-ts |
| 🟠 Alfa | Experimental, 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— consomepaebiru-ccomo 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-kernelestá 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 passapaebiru_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_casecom sufixo_t(paebiru_node_t,paebiru_receipt_t) — convenção POSIX. - Erros em
paebiru_error_tenum ou retornandoint(negativo em erro, 0 em sucesso) —inté mais simples para ABI stability. - Macros e constantes em
UPPER_SNAKE_CASEcom prefixoPAEBIRU_(PAEBIRU_DEFAULT_PORT,PAEBIRU_MAX_PLASMID_SIZE).
- Todas as funções e tipos começam com
- 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 viapkg-config,vcpkg,Conan, ou como target CMakefind_package(paebiru). Headerpaebiru.hem/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/_destroydevem 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_eventretorna 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Dogma 4 · Interoperabilidade Blindada (Zero-Copy) — diretriz arquitetural
- Binding Python (
paebiru-py) — consome via PyO3 - Binding Java (
paebiru-java) — consome via JNI - Binding C# (
paebiru-csharp) — consome via P/Invoke - Binding Delphi/Object Pascal — consome via
external - Binding Ada/SPARK — consome via
pragma Import - Binding Dart (
paebiru-dart) — consome viadart:ffi - Binding Lua (
paebiru-lua) — consome via mlua - Binding PHP (
paebiru-php) — consome via ext-php-rs - Binding R (
paebiru-r) — consome via extendr - Binding Ruby (
paebiru-ruby) — consome via Magnus - Binding Swift (
paebiru-swift) — consome via UniFFI - Binding TypeScript/WASM — consome via wasm-bindgen
- Binding Zig — consome via
@cImport - Binding Elixir (
paebiru-elixir) — consome via Rustler - Binding Julia (
Paebiru.jl) — consome via@ccall - Binding COBOL — consome via
CALL - Binding Haskell (
paebiru-haskell) — consome viaforeign import capi - Binding Fortran — consome via
iso_c_binding - Binding MATLAB/Octave — consome via MEX C
- Binding Prolog (
paebiru-prolog) — consome viaforeign/c_lib - Binding Go (
paebiru-go) — consome via cgo - Binding Elixir (
paebiru-elixir) — consome via Rustler - BC Kernel
🟦 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 vincularpaebiru-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 chamampaebiru_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-kernelestá 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 porstd::unique_ptr<opa::node, opa::node_deleter>com deleter customizado que chamapaebiru_node_destroyno 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-casedentro deinline constexpr namespace(estilo moderno):inline constexpr auto max_cid_bytes = 32;. - Membros privados com sufixo
_(estilo Google/Chromium) ou prefixom_(estilo Qt/Boost) — documentado como escolha do projeto. - Namespaces:
paebirupara API pública,paebiru::detailpara implementação. - Concepts:
concept MeshEventHandlerpara duck typing.
- Classes, structs, enums em
- 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_ptrgerenciar 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
FetchContentno 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 viareinterpret_cast<std::byte const*>. Compatível comstd::vector,std::array,std::string_view, e raw pointers. std::expected<T, Error>para error handling (C++23): análogo aResult<T, E>em Rust. Sem exceções, sem tratamento implícito — o caller deve inspecionar o resultado. Para C++20, usetl::expected(header-only).- Coroutines para async event streams (C++20):
Generator<MeshEvent> Node::events()produz eventos viaco_yield. Casa com ranges (C++20) e views (std::views::filter,std::views::take). - Modules para organização (C++20):
export module paebiru;empaebiru.cppmsubstitui 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_mutexpor 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.noexceptem 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base consumida viaextern "C" - Binding Python (
paebiru-py) — equivalente scripting - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Delphi/Object Pascal — equivalente enterprise
- Binding Ada/SPARK — equivalente safety-critical
- Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro FFI direto
- Binding Elixir (
paebiru-elixir) — equivalente BEAM - Binding Julia (
Paebiru.jl) — outro FFI direto - Binding COBOL — equivalente mainframe
- Binding Haskell (
paebiru-haskell) — equivalente funcional puro - Binding Fortran — equivalente HPC
- Binding MATLAB/Octave — equivalente numérico
- Binding Prolog (
paebiru-prolog) — equivalente lógica - Binding Go (
paebiru-go) — equivalente cloud-native - BC Kernel
🐍 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-learne 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(viapaebiru-rust) como módulo Python nativo, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, com__init__.pystrict,dataclass(frozen=True)paraReceipteMeshEvent, context managers (with) para cleanup determinístico,async/awaitpara hot-path, enumpy.frombuffer/torch.frombufferpara zero-copy de buffers nativos.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 umc_void_p(ponteiro opaco vindo de Rust via PyO3).__del__chamapaebiru_node_destroyquando 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)paraReceipt.
- Classes em
- 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.finalizeoferece cleanup mesmo com referência circular. - Distribuição: pacote PyPI
paebiru(instalação viapip install paebiru). Wheels manylinux/musllinux/macOS/ Windows viacibuildwheel. Para NumPy/PyTorch integration, extras_require:paebiru[numpy],paebiru[torch],paebiru[jax]. - Type safety:
from __future__ import annotations+mypy --strictgarante que a API é type-safe. Protocol classes (MeshEventHandler) para structural typing. - Async/await:
asyncionativo para hot-path;AsyncIterator[MeshEvent]para stream de eventos viaasync for. Casa comaiohttp,httpx,asyncio.gather. - Zero-cópia via NumPy/PyTorch:
numpy.frombufferpara interpretar memória C comonumpy.ndarray;torch.frombufferparatorch.Tensor. Ambas evitam cópia vianp.ndarray.baseapontando paractypesraw. - PEP 544 Protocols para interfaces duck-typed:
class MeshEventHandler(Protocol): def __call__(self, event: MeshEvent) -> None: ... matchstatement (Python 3.10+) para discriminação deMeshEvent.type:match event: case PeerConnected(peer_id): ... case PeerLost(peer_id, reason): ... case ReceiptProduced(receipt): ...__repr__explícito para debug:repr(node)mostraNode(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 syntaxX | 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida via PyO3 - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Delphi/Object Pascal — equivalente enterprise
- Binding Ada/SPARK — equivalente safety-critical
- Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro FFI direto
- Binding Elixir (
paebiru-elixir) — equivalente BEAM - Binding Julia (
Paebiru.jl) — outro FFI direto - Binding COBOL — equivalente mainframe
- Binding Haskell (
paebiru-haskell) — equivalente funcional puro - Binding Fortran — equivalente HPC
- Binding MATLAB/Octave — equivalente numérico
- Binding Prolog (
paebiru-prolog) — equivalente lógica - Binding Go (
paebiru-go) — equivalente cloud-native - BC Kernel
- BC Aprendizado — FedAvg/FL
🕸️ 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 parawasm32-unknown-unknownviawasm-bindgene exposto com tipos TypeScript gerados automaticamente, seguindo o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, comArrayBuffer/SharedArrayBufferpara zero-copy via WASM linear memory.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 umnumber(índice em uma tabela de handles do lado WASM) ou umBigInt(offset na WASM linear memory). O tipoPaebiruNodeé uma classe TypeScript fina que mantém o handle em um campoprivate readonly #handle: numbere 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').
- Classes e tipos em
- Gerenciamento de memória: o
PaebiruNodeexpõeasync close(): Promise<void>(chamapaebiru_node_destroyvia WASM). Para cleanup automático comusing(TS 5.2+):using node = await Node.init(...);— oSymbol.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 viafetch+instantiateStreaming)dist/types/(declarações.d.tsgeradas)
- TypeScript strict: API é totalmente tipada; sem
anyem hot-path;noUncheckedIndexedAccess: truenotsconfig.jsonrecomendado. - Async-first: toda API pública retorna
Promise<T>ou é umAsyncIterable<T>. Casas com a metáfora de eventos do Kernel GALS. - Zero-cópia via
ArrayBuffer:- Payloads entram/saem como
Uint8Array(vista sobreArrayBuffer). - Quando disponível,
SharedArrayBufferpermite ao host e ao WASM compartilharem memória sem cópia (necessita COOP/COEP headers no servidor).
- Payloads entram/saem como
- 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 1000000emwasmtime). - Sem syscalls host: o
paebiru-cnão chama nada fora das APIs expostas viawasm-bindgen. Não há acesso alocalStorage,fetch, ou DOM a partir do WASM — apenas viahost importsdeclarados. - 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 viaSharedArrayBuffer, o servidor deve retornar:Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp - Subresource Integrity (SRI): o
paebiru.wasmdeve 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
- WASI-PAEBIRU ABI
- BC API
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI compilada para WASM - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web server - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - BC Kernel
🐹 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,cobrapara 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, comcgo.Handlepara gerenciar lifetime de structs C com segurança,runtime.SetFinalizerpara cleanup via GC, channels (chan) para stream de eventos,context.Contextpara cancelamento, e generics (Go 1.18+) para APIs type-safe.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 comocgo.Handle(umuintptrtype-safe) que mapeia para um struct interno contendo o ponteiro C opaco.cgo.Handlepermite garbage collection cooperativo entre Go e C — cleanup viacgo.Handle.Delete(handle)ou automático viaruntime.SetFinalizer(node, ...)que chamapaebiru_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
PascalCaseouUPPER_SNAKE(DefaultPort,MAX_PLASMID_SIZE). - Interfaces em
PascalCasecom sufixo-erquando descreve comportamento (MeshEventer).
- Pacotes em
- Gerenciamento de memória:
defer node.Close()para cleanup imediato;runtime.SetFinalizerpara cleanup via GC caso o usuário esqueça.cgo.Handleregistra a struct Go↔C com segurança de tipos. - Distribuição: módulo Go
github.com/paebiru/paebiru-go(importação viago get). CGO_ENABLED=1 por default (necessário paralibpaebiru). context.Contextpara cancelamento: toda operação longa aceitactx context.Contextpara cancelamento cooperativo (casa com cancelamento de goroutines viactx.Done()).- Channels para eventos assíncronos:
<-chan MeshEventpara consumir eventos da malha — modelagem canônica Go para streams. - Generics para type safety (Go 1.18+):
EventOf[T any]permite APIs parametrizadas seminterface{}/anypoluído. - Errors como valores:
errorinterface Go é o canônico; nada de exceções. Wrap comfmt.Errorf("paebiru: %w", err). - Testabilidade nativa:
testingpackage para unit tests,testing.Bpara benchmarks,go test -fuzzpara fuzzing. - Zero-cópia via
unsafe.Pointer: payloads podem ser passados como[]bytecom slice header apontando para memória C (comunsafe.Slice); alternativa mais segura é copiar viaC.GoBytes.
2. Instalação
go get github.com/paebiru/paebiru-go
Pré-requisitos
- Go ≥ 1.21 (para generics maduros,
slices,mapsstdlib) - 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida via cgo - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Delphi/Object Pascal — equivalente enterprise
- Binding Ada/SPARK — equivalente safety-critical
- Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro FFI direto
- Binding Elixir (
paebiru-elixir) — equivalente BEAM - Binding Julia (
Paebiru.jl) — outro FFI direto - Binding COBOL — equivalente mainframe
- Binding Haskell (
paebiru-haskell) — equivalente funcional puro - Binding Fortran — equivalente HPC
- Binding MATLAB/Octave — equivalente numérico
- Binding Prolog (
paebiru-prolog) — equivalente lógica - BC Kernel
☕ 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-kernelestá 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 umlongde 64 bits que encapsula o ponteiro opaco produzido pelopaebiru-c. A classeNodeguarda esse handle em um campoprivate final longe nunca o expõe fora do JNI. - Convenção de nomenclatura: prefixo
Paebiru(PascalCase) em classes, métodos emcamelCase(JavaBeans), constantes emUPPER_SNAKE_CASEpara enums. - Gerenciamento de memória: classes que carregam handle nativo
implementam
AutoCloseablee devem ser usadas comtry-with-resourcespara garantirpaebiru_node_destroymesmo em caso de exceção. - Pacote raiz:
org.paebiru(reservado; mirror do namespacepaebiruno JNI). - Sem alocação em hot-path: callbacks registrados via
MessageHandlerrecebem umByteBufferdireto (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
StrictModepara detectar chamadas bloqueantes vindas do JNI em main thread. - Prefira
PaebiruAsyncClient(wrapper de coroutines) a bloquear comFuture.get(). - Em background, escute mudanças de topologia via
MeshObserver(callback registrado antes denode.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, comSpan<T>/ReadOnlySpan<T>para evitar cópias intermediárias.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 pornuint(ponteiro nativo opaco) — nuncaIntPtrlegado. A structNodeguarda esse handle em um camporeadonlyprivado e o expõe ao P/Invoke vianuintquando necessário. - Convenção de nomenclatura: prefixo
Paebiru(PascalCase) em tipos públicos, métodos emPascalCase(.NET), membros internos em_camelCase(padrão StyleCop). - Gerenciamento de memória: tipos que carregam handle nativo
implementam
IAsyncDisposable(não apenasIDisposable) e devem ser usados comawait usingpara garantirpaebiru_node_destroymesmo 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 recebemSpan<byte>mutável. Nunca alocarbyte[]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; useasync UniTask(pacote UniTask) ou jobs Unity para latência determinística. - Compartilhe a malha PAEBIRU entre múltiplas cenas via
PaebiruNode.CreateAsyncemRuntimeInitializeOnLoadMethod.
.NET MAUI (mobile/desktop cross-platform)
- Em background, use
PeriodicTimerpara drenar a fila de receipts semThread.Sleep. - Para Android, marque
uses-permissionparaINTERNETeACCESS_NETWORK_STATEnoAndroidManifest.xml. - Para iOS, habilite
NSAppTransportSecurityapenas 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-wasmcom NativeAOT. - Hot-path de mensagens deve usar
IJSUnmarshalledRuntimepara 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI - Binding Java (
paebiru-java) — equivalente JVM - BC Kernel
🏛️ 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
externalda Object Pascal para vincular diretamente alibpaebiruvia 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, comPointerpara handles opacos,TBytespara 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-kernelestá 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 comoPointer(ponteiro opaco). Encapsuladas em uma classeTPaebiruNodeque mantém o handle em um campoprivate FHandle: Pointere nunca o expõe fora da unit. - Convenção de nomenclatura:
- Units em
Paebiru(singular, sem prefixou). - Classes com prefixo
T(TPaebiruNode,TReceipt,TMeshEvent). Tipos exceção com sufixoException(EPaebiruError). - Métodos e propriedades em
PascalCase(Start,SendMessage,MicroJoules). - Constantes em
UPPER_SNAKE_CASEoucamelCasecom prefixo (PAEBIRU_DEFAULT_PORT). - Fields privados com prefixo
F(FHandle,FStorage).
- Units em
- Gerenciamento de memória: classes que carregam handle
implementam
destructor Destroy; override;(chamapaebiru_node_destroy). Em código de chamada, usetry ... finally Obj.Free; end;para cleanup garantido. - Distribuição: package via GetIt (Embarcadero) ou
manualmente via
bpl/dcp(Borland Package Library). Para FPC, viafppkgou git clone. externalpara FFI C: declaração de funções C comcdecl; external 'paebiru.dll'(Windows) ouexternal 'libpaebiru.so'(Linux). Calling convention canônico:cdecl.- Records com métodos (advanced records): tipos de valor
imutáveis como
TReceipt,TMeshAddresssãorecordcom 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 procedurepara callbacks de eventos — mais idiomático que interfaces. - TParallel / TTask (Delphi RTL): paralelismo e
async/await.
TTask.Runpara fire-and-forget,await(Delphi ≥ 10.3) para await de TTask. - Zero-cópia via
Pointer+TBytes:TByteséarray of Bytedynamic; pode ser passada comoPByte(@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 paraRawByteString/UTF8Stringquando 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.bplou 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida viaexternal - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web server - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro binding direto sem crate Rust
- Binding Elixir (
paebiru-elixir) — equivalente BEAM/GALS - Binding Julia (
Paebiru.jl) — outro binding direto sem crate Rust - BC Kernel
- BC HAL — alvo embarcado (via FPC + target ARM)
🛡️ 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 pacoteInterfaces.Cpara vincularpaebiru-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.Controlledpara cleanup determinístico viaFinalizechamandopaebiru_node_destroy, e tasking nativo (tasks + protected objects) para concorrência first-class.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 portype Paebiru_Node is new Ada.Finalization.Controlled with private;—Controlledgarante queFinalize (This : in out Paebiru_Node)é chamado deterministicamente quando o objeto sai de escopo (não depende de GC como ForeignPtr do Haskell). Oprivateesconde o handle C da API pública. - Convenção de nomenclatura:
- Tipos em
PascalCaseouSnake_Case_With_Underscores(comunidade Ada usa ambos; estilo GNAT prefereSnake_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ãoUPPER_SNAKE). - Tipos child:
Paebiri.Mesh,Paebiri.Receipt,Paebiri.Events.
- Tipos em
- Gerenciamento de memória determinístico:
ControlledcomInitialize(chamapaebiru_node_create) eFinalize(chamapaebiru_node_destroy) — sem ambiguidade, sem GC, sem refcount. - Distribuição: package Alire (
alr install paebiru), index Alire index, ou git viaalr 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_Modepara marcar subprogramas como verificáveis;pragma Assume,pragma Assertpara 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_Conversionpara 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida viapragma Import - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Delphi/Object Pascal — equivalente enterprise
- Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro FFI direto
- Binding Elixir (
paebiru-elixir) — equivalente BEAM - Binding Julia (
Paebiru.jl) — outro FFI direto - Binding COBOL — equivalente mainframe
- Binding Haskell (
paebiru-haskell) — equivalente funcional puro - BC Kernel
🎯 Dart (paebiru-dart)
O binding Dart integra o PAEBIRU em Flutter (mobile, web, desktop) e em servidores Dart puros. Utiliza
dart:ffisobre a base FFI C (paebiru-c) e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON, sem reflection em hot-path, comPointer<Uint8>/Uint8List.viewpara 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-kernelestá 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 porPointer<Void>opaco. A classePaebiruNodeguarda esse ponteiro em um campofinalprivado e o expõe ao FFI apenas dentro de métodos@Nativeisolados. - Convenção de nomenclatura: prefixo
Paebiru(PascalCase) em tipos públicos, métodos emlowerCamelCase(Effective Dart), constantes emlowerCamelCase(nãoUPPER_SNAKE). - Gerenciamento de memória: o binding expõe
close()síncrono e oPaebiruNodeimplementa o mixin padrão do pacotepackage:resourcepara uso comtry/finallyewithblocks (Dart 3+). - Pacote raiz:
paebiru(reservado empub.dev). - Null-safety estrita: a API é non-nullable por padrão;
opcionais usam
T?explicitamente. Semdynamicem 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.spawnpara não travar a UI thread. - Zero-cópia: payloads de mensagem trafegam como
Uint8List.view(vista sobre buffer nativo) ouPointer<Uint8>. Nunca copiar bytes paraUint8List.fromListem hot-path. - Dart 3+ features: usa
sealed classpara ADTs (ex:Receipt,MeshEvent),recordtypes para tuplas imutáveis, epattern matchingno 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.addPostFrameCallbackpara não inicializar o nó no meio de um frame (causa jank). - Em hot-reload, libere o nó via
RefenaouRiverpodlifecycle hook — handles órfãos vazam memória nativa. - Para Android, declare permissão
<uses-permission android:name="android.permission.INTERNET" />. - Para iOS, configure
NSLocalNetworkUsageDescriptionnoInfo.plistpara descoberta mDNS. - Para Web, o binding carrega a
libpaebiru.wasmviapackage: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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - BC Kernel
📜 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
CALLcom cláusulasBY REFERENCEeBY VALUE(GnuCOBOL ≥ 3.0) para invocar funçõespaebiru-cdeclaradas emLINKAGE SECTION, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, comUSAGE POINTERpara handles opacos,PIC X(n)para buffers de tamanho fixo, eUSAGE BINARY/COMP-3para inteiros decimais packed (que COBOL manipula nativamente, sem ponto flutuante).
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 comoUSAGE POINTER— o tipo COBOL para ponteiros opacos vindos de C. ALINKAGE SECTIONdeclara o ponteiro, e a working-storage mantém uma cópia (já queLINKAGEé read-only). - Convenção de nomenclatura:
- Variáveis e copybooks em
UPPER_SNAKE_CASEouHyphenated— 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.
- Variáveis e copybooks em
- Gerenciamento de memória: COBOL não tem
malloc/freediretos, mas GnuCOBOL expõeCBL_ALLOC/CBL_FREEda CBL_GC_HOSTED API. Para o handle, o programa declara o ponteiro e a rotinaPAEBIRU-DESTROY-NODEchamapaebiru_node_destroyviaCALL. - Distribuição: copybooks (
.cpy) + scripts de build (Makefile/CMake) +libpaebiru.solinkado. 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.), usarBY CONTENTouBY REFERENCEcomWORKING-STORAGEcomo buffer. - Decimal arithmetic nativa: COBOL tem
USAGE COMP-3(packed decimal) — perfeito paraMICRO-JOULESeRECEIPT-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 programaENVIRONMENT DIVISION.— configuração (calls externos)DATA DIVISION.—WORKING-STORAGE,LINKAGE,FILEPROCEDURE DIVISION.— lógica
- PERFORM ao invés de funções: COBOL usa
PERFORM paragraph-namepara chamar “sub-rotinas” (análogo a funções) — não háfunctionkeyword. EVALUATEao invés de switch:COBOL 85+temEVALUATEcomWHENclauses — equivalente estruturado ao switch/case.STRINGeINSPECT: manipulação de strings viaSTRING ... DELIMITED ... INTO ...eINSPECT ... TALLYING/REPLACING/CONVERTING.- Inline C via
CALL "C" USING: GnuCOBOL permite chamar funções libc diretamente — útil paramemcpy,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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida viaCALL - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Delphi/Object Pascal — equivalente enterprise/Windows
- Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web server - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro FFI direto
- Binding Elixir (
paebiru-elixir) — equivalente BEAM - Binding Julia (
Paebiru.jl) — outro FFI direto - BC Kernel
- BC DRE (Recibo Soberano)
💧 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
Rustlerpara expor opaebiru-ccomo NIF (Native Implemented Function), e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, comResourceArcpara ownership seguro de structs Rust no BEAM,GenServerpara hospedar o estado do nó, eSupervisorpara auto-restart em caso de falha algedônica.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 porT(struct interna), wrappadas emResourceArc<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_caseoukebab-case(:connected,:peer_lost,:receipt_produced). - Tuplas de retorno:
{:ok, value}ou{:error, reason}— convenção Elixir universal.
- Módulos em
- Gerenciamento de memória:
ResourceArc<T>decrementa refcount quando a referência Elixir é coletada pelo GC do BEAM; ao chegar a zero, oDropem Rust chamapaebiru_node_destroy. Para cleanup explícito,GenServer.stop(node)é o caminho idiomático. - Distribuição: pacote Hex
paebiru(reservado). GenServerpara o estado do nó: oPaebiru.Nodeé umGenServer— calls síncronas (GenServer.call), casts assíncronos (GenServer.cast),handle_infopara eventos do Kernel. Casa com oKernelActordo PAEBIRU.- Padrão de retorno
{:ok, _} | {:error, _}: NIFs convertem retornos Rust em tuplas Elixir — facilita pattern matching e pipe. - Pattern matching: o consumidor usa
caseematch?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 comobinary(que éu8[]zero-copy no BEAM). Para fluxos10 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/3melhorias) - Sistema:
libpaebiru.so/.dylib/.dll— distribuída como precompiled NIF viaRustlerPrecompiled(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.MeshChannelpara 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 viachannel.on("mesh_event", ...)e atualize LiveView assigns — o frontend recebe Cada recibo Soberano em < 100 ms. - Exponha REST em
router.expara 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 PAEBIRU | Conceito Erlang |
|---|---|
PeerId | <node>@<host> (ex: node1@192.168.1.10) |
GossipSub | :rpc.call / :gen_server.cast |
MeshEvent | Process (cada peer = um processo) |
Receipt | Message 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida por Rustler - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web server - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — equivalente sistemas
- BC Kernel
- BC HAL — alvo Nerves embarcado
λ 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 paraMeshEvente processos PAEBIRU.O binding usa
foreign import capi(FFI para C, com marshaling de tipos viaStorable) para vincularpaebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, comForeignPtr(com finalizer) para ownership seguro de handles C,ByteStringpara buffers zero-copy, eMaybe/Eitherpara tratarnull/erros semnullem runtime.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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
ForeignPtrcom finalizer: instâncias nativas (nó, identidade, recibo) são representadas pordata PaebiruNode = PaebiruNode {-# UNPACK #-} !(ForeignPtr CPaebiruNode). OForeignPtrgerencia refcount e dispara um finalizer registrado viaForeign.newForeignPtrque chamapaebiru_node_destroyquando o GC de Haskell coleta o último reference — análogo aRc<T>comDropem 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
camelCaseousnake_case(comunidade dividida; moderno écamelCase). - Tipos ADT e de erro:
data PaebiruError = NetworkError | OutOfMemory | Unknown | ... - Módulos em
PascalCase(Network.Paebiru.Mesh).
- Tipos, construtores em
- Gerenciamento de memória:
ForeignPtr+ finalizer cuida de cleanup automático. Para cleanup imediato,withForeignPtrpermite 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,
IOapenas para side effects (C interop, I/O). ZerounsafePerformIOem código de aplicação — apenas dentro do binding (necessário para chamar C). - Type classes para abstração:
Permite que tipos PAEBIRU e tipos de usuário implementem serialização canônica.class ToBytes a where toBytes :: a -> ByteString class FromBytes a where fromBytes :: ByteString -> Either String a - 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) Maybepara null,Eitherpara erro: semnullem runtime; o sistema de tipos força tratamento explícito.ByteStringpara buffers binários: muito mais eficiente queString(lazy) ouData.ByteString.Char8para I/O binário.ByteStringé oTBytesde Haskell.Textpara strings Unicode: eficiente (packed UTF-16 array) eO(1)length, vsStringlazy.- Storable typeclass: implementada por todos os tipos
que atravessam fronteira FFI — permite
peek/poketype-safe viawith/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
Via Stack (alternativa popular)
# 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 viaextra-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 viaSendPort - DProcess (distributed process) abstrai location transparency
- Gera automaticamente serialização de tipos via
deriving Typeable - Distributed supervision de
meshNodeProcessviawhereisRemoteAsync
5. Veja também
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida viaforeign import capi - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Delphi/Object Pascal — equivalente enterprise
- Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro FFI direto
- Binding Elixir (
paebiru-elixir) — equivalente BEAM/GALS - Binding Julia (
Paebiru.jl) — outro FFI direto - Binding COBOL — equivalente mainframe
- BC Kernel
🍎 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, comactor(Swift 5.5+) para concorrência segura,async/awaitpara hot-path, eAsyncStreampara eventos.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 tiposfinal classem Swift, mas expostas comoactor PaebiruNode(Swift 5.5+). Oactorgarante isolamento de memória entre tasks concorrentes — casa naturalmente com o GALS do PAEBIRU. - Convenção de nomenclatura:
actor,struct,enum,class,protocolemUpperCamelCase(PaebiruNode,MeshEvent).- Métodos, propriedades e funções em
lowerCamelCase(start(),sendMessage(target:payload:),microJoules). - Constantes em
lowerCamelCase(nãoUPPER_SNAKE). Sendableaplicado 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.
deinitchamapaebiru_node_destroyautomaticamente. Não háclose()manual — apenas deixe o actor sair de escopo. Para cleanup imediato, chameawait node.shutdown(). - Distribuição: pacote SwiftPM com
Package.swiftdeclarando a dependência binária paralibpaebiru. Distribuído via Swift Package Index. - Async-first: toda API pública é
async(ouasync throws). O binding não expõe APIs síncronas (exceto construtores puros). Resultouthrows: erros do lado Rust são convertidos parathrowsSwift (mais idiomático) —enum PaebiruError: Errorcasa com as variantes do Rust.- Structs imutáveis:
Receipt,MeshAddresssãostructcomletem todos os campos — zero mutação após criação. Conforma comSendableautomaticamente. - Enums com associated values:
MeshEventéenumcom casospeerConnected(PeerId),peerLost(PeerId, reason: String),receiptProduced(Receipt)— pattern matching viaswitch. - Combine para reativos: o binding expõe
AsyncStream<MeshEvent>e também um wrapperPublisher<MeshEvent>para integração com SwiftUI / Combine. - SwiftUI-ready: o pacote expõe
PaebiruNodecomo@StateObject/@ObservedObjectpara 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+@MainActorpara garantir que mutações de@Publishedocorram na main thread. - Em
SceneDelegateouApp, não chamestart()no init (sync) — chame no.taskda view para usar async/await corretamente. - Para background fetch, configure
BGAppRefreshTasknoInfo.pliste processe eventos recebidos durante o background. - Para Push Notifications (notificar recibo crítico),
integre via
UNUserNotificationCenterno callback dereceiptProduced. - 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
Combinepara 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;deinitchamapaebiru_node_destroy.
SwiftWasm (rodando no navegador)
- Compile o binding com SwiftWasm 5.9 toolchain.
- Use
AsyncStreampara consumir eventos da malha diretamente em JavaScript viaJSExport. - Limite de memória do WASM (~4 GB) impõe batching de mensagens > 10/s.
5. Veja também
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida por UniFFI - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - BC Kernel
💎 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
Magnuspara expor classes Ruby idiomáticas sobre opaebiru-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, eFiber(3.0+) para async cooperativo.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 oVALUE(ponteiro opaco) dopaebiru-c. A classe mantém o handle em uma instância@handlee expõe métodos de domínio. - Convenção de nomenclatura:
frozen_string_literal: trueem 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; chamapaebiru_node_destroyquando o objeto é coletado. Para cleanup explícito,#closeé fornecido (libera imediatamente, sem esperar GC). - Distribuição: gem
paebiruno RubyGems combundle add paebirupara 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 queProc.newoulambdaexplícito). - Fiber para async (Ruby 3.0+): o binding expõe eventos via
Fiber.yieldeFiber#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 viacase ... 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 porextensions:emextconf.rbou prebuilt viapaebiruRust 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
#closeno 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida por Magnus - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - BC Kernel
🐘 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 Rustext-php-rspara 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 ereadonly class(PHP 8.2+) para tipos imutáveis.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 umintde 64 bits (Zendzend_long) que encapsula o ponteiro opaco. A classePaebiru\Sdk\Nodeguarda esse handle em propriedadeprivate readonly int $handlee nunca o expõe fora da extensão. - Convenção de nomenclatura: namespace raiz
Paebiru\Sdk; classes emPascalCase(PSR-12), métodos emcamelCase, constantes emUPPER_SNAKE_CASE(compat PHP 8.1enum). - Gerenciamento de memória: classes que carregam handle
implementam
__destruct(legado) e limpeza viatry/finally(recomendado). Em Swoole/AMPHP, registreregister_shutdown_functionpara cleanup em caso de fatal. - Distribuição: pacote Composer
paebiru/paebiru-php+ extensão.so/.dllinstalada via PECL ou pré-compilada nophp.ini. - Tipagem forte: a API pública é totalmente tipada (PHP 8.2+)
—
readonly class,enum, intersection types,neverreturn type. Semmixedem hot-path. - Zero-cópia: payloads de mensagem trafegam como
stringPHP (que échar*no Zend) ouSplFixedArrayde inteiros para hot-path binário. Nuncajson_encodeem 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óprioNode, não compartilhe entre coroutines semchanouAtomicpara serializar. - Use
Swoole\Coroutine\Channelpara passar eventos entre coroutines que escutam a mesma malha PAEBIRU. - Configure
swoole.use_shortname = 'Off'para evitar conflito comFiber.
WordPress (plugin emitindo Recibos Soberanos)
- Crie o
Nodeemplugins_loaded(hook); guarde em variável global$GLOBALS['paebiru_node']. - Em
wp_ajax_*ewp_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_contentfilter; enviar Recibos Soberanos nesse ponto causa flood de receipts. Faça emwp_loadedoutemplate_redirect.
Laravel (framework full-stack)
- Crie um
ServiceProviderque inicializa oNodecomo singleton no container:$this->app->singleton(Node::class, fn() => new Node( config('paebiru.storage_path') )); - Exponha configuração em
config/paebiru.phplendo 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
Nodecomo serviço comautowirepor type-hint. - Use o Messenger component para enfileirar Recibos Soberanos como mensagens assíncronas processadas em workers separados.
5. Veja também
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida por ext-php-rs - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - BC Kernel
🌙 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
mluapara fazer a ponte entre opaebiru-ce o estado Lua, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, comuserdataopaco e metatables para a API OO.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 poruserdataLua contendo um*mut c_void. Acessos passam por uma metatable com__index,__newindex,__gc(finalizer que chamapaebiru_node_destroy). - Convenção de nomenclatura: módulo raiz
paebiru(minúsculo); tipos exportados emPascalCaseglobal (paebiru.PaeNode,paebiru.PaeReceipt); métodos emlowerCamelCase(paeNode:start()). - Gerenciamento de memória: a
__gcmetamethod garantepaebiru_node_destroyquando ouserdataé coletado. Recomenda-sepcall(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 detype(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.cdefpara chamadas zero-overhead aopaebiru-c, em Lua 5.x cai para a API C viamlua.
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, chamenode:start()e armazene o handle em variável global; não recrie o nó emlove.update(causa leak do userdata). - Em
love.draw, usecoroutine.status(co)para renderizar apenas quando há eventos pendentes. - Em
love.quit, chamenode: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.defoldque expõe uma API OO cominit,final,on_message,on_input. - Hot-reload do editor: o binding desregistra callbacks no
finalpara 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 eminit_worker_by_lua_block(roda por worker, multiplica handles). - Em
content_by_lua_block, exponha endpoints que consultamnode:status()ou injetam plasmídeos vianode: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-limitalto (≥ 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida por mlua - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - BC Kernel
📊 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
extendrpara gerar bindings R idiomáticos sobre opaebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, comR6::R6Class(POO moderna em R),tryCatchpara erros, e ponte direta paradata.table/arrow/torchviaALTREPquando aplicável.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 porexternalptr— o tipo canônico do R para ponteiros opacos vindos de C/Rust. A classeR6::R6ClassPaebiruNode$new()envolve oexternalptre expõe métodos$start(),$send_message(), etc. O finalizer (finalize = TRUEno R6) chamapaebiru_node_destroyquando o objeto é coletado pelo GC. - Convenção de nomenclatura: pacote raiz
paebiru(em R é minúsculo e sem_); classes R6 emPaebiruNode(PascalCase, expostas comopaebiru::Node); métodos emsnake_case($send_message(),$on_message_received()) para casar com o estilo tidyverse. - Gerenciamento de memória: R6 com
finalize = TRUEchama o destrutor automaticamente no GC. Para cleanup explícito,$close()é fornecido (libera imediatamente, sem esperar GC). - Distribuição: pacote CRAN
paebirucomBioconductorcomo 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 etryCatch()para capturar erros. Vetores são usados em vez de coleções tipadas. - Zero-cópia:
raw(vetor de bytes brutos) enumericsão recebidos viaALTREPquando o lado Rust expõeAltRep— evita cópia de buffers grandes.- Para DataFrames grandes, integre com
arrow(Apache Arrow) viapaebiru_node$query()que retorna umTableArrow 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
plumberpara expor o nó PAEBIRU como API REST; o binding expõenode$as_plumber_preroute()para integração automática.
5. Veja também
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida por extendr - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - BC Aprendizado
- BC Kernel
🟪 Julia (Paebiru.jl)
O binding Julia é, junto com Zig, um dos dois únicos que consomem
paebiru-cdiretamente 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 (viaFlux.jl/Lux.jl), Langevin dynamics (viaDifferentialEquations.jl), ZK number theory (viaNemo.jl), estatística da malha (viaDataFrames.jl), e GPU acceleration (viaCUDA.jl/AMDGPU.jl/Metal.jl/oneAPI.jl).O binding usa
@ccall(macro moderna, type-safe, sobreccall) para chamarlibpaebiru, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, commutable structpara ownership do handle C,Channelpara eventos assíncronos, eBase.Ref/unsafe_wrappara zero-copy viaPtr{T}.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 pormutable struct PaebiruNode handle::Ptr{Cvoid} end(ouRef{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).
- Módulos, tipos, structs em
- Gerenciamento de memória:
Base.close(node::Paebiru.Node)chamapaebiru_node_destroyvia@ccall. Usetry / finallypara garantir cleanup, ou use oBlockpackage (Julia ≥ 1.9) comcloseem escopo léxico. - Distribuição: pacote Julia
Paebiru(registrado comoPaebiru.jlno JuliaGeneral). Importação viausing 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. Channelpara eventos assíncronos:Channel{MeshEvent}(sz)é o canônico Julia para stream de eventos entre tasks (similar aStream<T>Dart,AsyncStream<T>Swift).- Zero-cópia via
Ptr{T}+unsafe_wrap: arrays Julia podem ser passados diretamente comoPtr{UInt8}para o lado C sem cópia, usandoBase.unsafe_wrappara criar umVector{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.jlresolve oPtr{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 emunsafe_wrap, pattern matching,@debugestruturado) - Sistema:
libpaebiru.so(Linux) /.dylib(macOS) /.dll(Windows) — instalável viajulia>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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Referência · Matemática — Ising e Langevin
- Binding C (
paebiru-c) — base FFI consumida via@ccall - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web server - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro binding direto sem crate Rust
- Binding Elixir (
paebiru-elixir) — equivalente BEAM/GALS - BC Aprendizado — FedAvg/FL
- BC Math — Ising/Langevin
- BC Kernel
🧮 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 atributobind(c)para vincularpaebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, comtype(c_ptr)para handles opacos,coarray(Fortran 2008+) para paralelismo distribuído entre nós do supercomputador, edo concurrentpara paralelismo intra-node com semântica SIMD/OpenMP.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 comotype(c_ptr)— o tipo canônico Fortran para ponteiros opacos vindos de C. Encapsuladas em umatype :: paebiru_node_t(tipo derivado) que mantém o handle em um campo privado. Cleanup viafinalbinding (Fortran 2018+) ou manual. - Convenção de nomenclatura:
- Tipos derivados e procedures em
snake_case(estilo moderno) oulowercase(estilo legacy) — comunidade Fortran está migrando parasnake_case. - Variáveis, constantes em
snake_case(storage_path,micro_joules). - Módulos em
snake_caseouPascalCase(community- divided; fpm favorecesnake_case). - Constantes em
snake_caseouUPPER_SNAKE(depende do estilo). - Sufixos:
kindpara precisão de tipo (integer(c_int32_t)),lenpara comprimento de string (character(len=*)).
- Tipos derivados e procedures em
- Gerenciamento de memória:
type, bind(c) :: paebiru_node_tcom membrotype(c_ptr) :: handle = c_null_ptr. Cleanup viafinal :: cleanup_node(Fortran 2018+) chamapaebiru_node_destroyquando o objeto sai de escopo. - Distribuição: package fpm (
fpm install paebiru) no Fortran-lang registry. Configuração viafpm.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 concurrentpara 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.pureeelementalmarcam 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. Substituicommon blockse arquivos.hde F77. - Derived types com
type, bind(c)(Fortran 2003+): para C interop, tipos derivados podem serbind(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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Referência · Matemática — Ising e Langevin
- Binding C (
paebiru-c) — base FFI consumida viaiso_c_binding - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Delphi/Object Pascal — equivalente enterprise
- Binding Ada/SPARK — equivalente safety-critical
- Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro FFI direto
- Binding Elixir (
paebiru-elixir) — equivalente BEAM - Binding Julia (
Paebiru.jl) — outro FFI direto - Binding COBOL — equivalente mainframe
- Binding Haskell (
paebiru-haskell) — equivalente funcional puro - BC Kernel
- BC Math — Ising/Langevin
🟦 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-ce 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, commxArraypara dados,mexMakeMemoryPersistent+mexMakeArrayPersistentpara ownership de handles, eparfor/spmd/gpuArraypara paralelismo nativo do Parallel Computing Toolbox.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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
mxArraycom tag persistente: instâncias nativas (nó, identidade, recibo) são representadas comomxArray*commexMakeMemoryPersistent+ tag custom para evitar GC do MATLAB. O handle C é armazenado nomxGetData(mx)(oumxGetPrpara double). Cleanup viamexAtExitregistra função que chamapaebiru_node_destroypara todos os handles ainda ativos no shutdown do MATLAB. - Convenção de nomenclatura:
- Funções em
snake_case(compat Octave) oucamelCase(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})
- Funções em
- Gerenciamento de memória: handles armazenados em
mxArraypersistente; cleanup viamexAtExit+ métododelete()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.gzviapkg install). - MEX C/C++ API:
mex.h(C) oumex.hpp(C++ moderno).mexFunction(nlhs, plhs, nrhs, prhs)é o entry point.mxCreateNumericMatrix,mxGetPr,mxGetData,mxArrayToString,mexCallMATLAB,mexEvalString. - Class wrapper MATLAB: classe
PaebiruNodecomclassdefque 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, usetimer+addlistener(evento) + callback function handle. - Parallel computing nativo:
parfor(parallel for-loop) — equivalente ado concurrentFortran ou OpenMP parallel for.spmd(single program, multiple data) — equivalente a coarray Fortran ou MPI SPMD.parclusterpara configurar o cluster local/cloud.distributedarray type para arrays em pool de workers.
- GPU computing:
gpuArraypara 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
4. Integração com parfor, spmd, gpuArray e Simulink
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);
Simulink (S-Function + MEX)
Para integrar PAEBIRU em modelos Simulink de controle (avião, robô, veículo autônomo):
- 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
- 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Referência · Matemática — Ising e Langevin
- Binding C (
paebiru-c) — base FFI consumida pelo MEX - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Delphi/Object Pascal — equivalente enterprise
- Binding Ada/SPARK — equivalente safety-critical
- Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro FFI direto
- Binding Elixir (
paebiru-elixir) — equivalente BEAM - Binding Julia (
Paebiru.jl) — outro FFI direto - Binding COBOL — equivalente mainframe
- Binding Haskell (
paebiru-haskell) — equivalente funcional puro - Binding Fortran — equivalente HPC
- BC Kernel
- BC Math — Ising/Langevin
♨ 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
foreigndeclarations +c_libpara vincularpaebiru-c, e segue o Dogma 4 · Opaque Handles & Zero-Copy — sem serialização JSON em hot-path, comterm_tpara marshaling,PL_foreign_tpara 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-kernelestá 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 viaPL_register_blob_type— Prolog gerencia o GC deles, e orelease()callback chamapaebiru_node_destroyquando o blob é coletado. Para handles temporários (dentro de um predicate), usa-sePL_open_foreign_frame+PL_rewind_foreign_framepara 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
lowercaseousnake_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).
- Predicados em
- Gerenciamento de memória:
PL_blob_tcomreleasecallback chamapaebiru_node_destroyquando o blob é coletado pelo GC do Prolog. Para cleanup imediato, usesetup_call_cleanup/3ouat_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).. Oc_lib(paebiru, [...])no foreign file carregalibpaebiru.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/3ouPL_open_foreign_frameno 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
clpfdpara auditoria discreta (ex: CIDs têm formato específico) eclprpara auditoria contínua (ex: micro_jouleslimiar).
- 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
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base FFI consumida peloforeign - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Delphi/Object Pascal — equivalente enterprise
- Binding Ada/SPARK — equivalente safety-critical
- Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- Binding Zig — outro FFI direto
- Binding Elixir (
paebiru-elixir) — equivalente BEAM - Binding Julia (
Paebiru.jl) — outro FFI direto - Binding COBOL — equivalente mainframe
- Binding Haskell (
paebiru-haskell) — equivalente funcional puro - Binding Fortran — equivalente HPC
- Binding MATLAB/Octave — equivalente numérico
- BC Kernel
⚡ 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 opaebiru-cdiretamente 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 (
freestandingmode), 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),
errdeferpara cleanup similar atry/finally, ecomptimepara abstrações zero-cost.
⚠️ Status atual (v0.0.2-0): apenas o crate
paebiru-kernelestá 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 comconst PaebiruNode = opaque {};(ouextern structquando 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— usastruct+ funções livres (paebiru_node_start(node: *PaebiruNode) noreturn).
- Tipos, structs, enums, unions em
- 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.GeneralPurposeAllocatorem desenvolvimento estd.heap.page_allocator(ou umArenaAllocatorscoped) em produção. - Cleanup via
errdefer: padrão equivalente atry/finally:errdefer node.destroy();garante quedestroyé chamado se qualquer operação subsequente falhar. - Erros como valores: Zig usa
error{X}!T(similar aResult<T, X>em Rust). O binding convertepaebiru_*que retornamintem 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 aenumSwift ou Rust:const MeshEvent = union(enum) { peer_connected: PeerId, peer_lost: struct { peer_id: PeerId, reason: []const u8 }, receipt_produced: Receipt, }; comptimepara zero-cost abstractions: funções genéricas comcomptime Tpermitem polimorfismo sem custo de runtime:fn Wrapper(comptime T: type) type { return struct { ... }; }.- Build via
build.zig: o pacote inclui umbuild.zigque vinculalibpaebiru(C) e expõe módulos Zig. Dependências viabuild.zig.zon+zig fetch.
2. Instalação
Aguardando primeira publicação do
paebiru-ccomo 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,comptimemaduro,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/awaitem 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.ArenaAllocatornomaine 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.printestd.logpara output estruturado. - Para CLIs que precisam de P2P, o
paebiru_node_send_messageemite 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.Threadpara workers com prioridade fixa. - Combine com
std.posix.mmappara I/O zero-copy em hot-path.
5. Veja também
- WASI-PAEBIRU ABI
- Design Assíncrono
- Binding C (
paebiru-c) — base consumida diretamente - Binding Java (
paebiru-java) — equivalente JVM - Binding C# (
paebiru-csharp) — equivalente .NET - Binding Dart (
paebiru-dart) — equivalente Flutter - Binding Lua (
paebiru-lua) — equivalente scripts - Binding PHP (
paebiru-php) — equivalente web server - Binding R (
paebiru-r) — equivalente estatística - Binding Ruby (
paebiru-ruby) — equivalente scripting - Binding Swift (
paebiru-swift) — equivalente Apple - Binding TypeScript/WASM — equivalente browser
- BC HAL — alvo embarcado
- BC Kernel
🎨 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:
| Eixo | Manifestação em UX |
|---|---|
| Biológico | A 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. |
| Fractal | O 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ágico | Devoramos 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):
- 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).
- 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.
- Pragmatismo de Hardware (
no_stdFirst) → 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). - 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).
| Token | Hex | RGB | Significado operacional |
|---|---|---|---|
--membrana | #1A6F5C | 26, 111, 92 | Verde-tucano profundo. Membrana saudável — barreira Bounded Context íntegra, nó conectado à malha. |
--correnteza | #3FA796 | 63, 167, 150 | Verde-água claro. Fluxo de CausalBlock na Correnteza (WAL, Prolly Tree). Movimento contínuo, sem atrito. |
--algedonia-dor | #C0392B | 192, 57, 43 | Vermelho-terra. Sinal de dor algedônica: XDP saturado, temperatura alta, saturação de memória, PoW falho. |
--algedonia-prazer | #D4A017 | 212, 160, 23 | Dourado-mel. Sinal de prazer algedônico: receipt validado, lote liquidado, peer autenticado. |
--manguezal | #5D4E8F | 93, 78, 143 | Roxo-cripta. Quarentena / MacrophageVM — pacote suspeito em análise, dado em apoptose. |
--oceano | #1B3A5C | 27, 58, 92 | Azul-profundeza. Cold storage / Oceano — dado em Maturidade Causal alta, $\Delta C \to 0$. |
--nascente | #E8F4F0 | 232, 244, 240 | Verde-claro quase branco. Nascente / ingestão hot-path — dado chegando, ainda em ring buffer. |
--ceu | #F4F1E8 | 244, 241, 232 | Off-white papiro. Fundo canônico da documentação e do background do CLI em modo claro. |
--tinta | #2B2A28 | 43, 42, 40 | Carvão. Texto primário sobre --ceu. Nunca use #000 puro. |
--sombra | #8C8478 | 140, 132, 120 | Argila. Texto secundário / bordas / divisores sobre --ceu. |
Convenção de uso: use uma cor algedônica por tela. Misturar
--algedonia-dore--algedonia-prazerno 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
| Camada | Fonte canônica | Por 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 customizada | Para 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=14nohelixou 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:
- Membrana (Bounded Contexts) — ícone quadrado com borda dupla
representando permeabilidade seletiva. Cor base:
--membrana. - Fluxo (CausalBlock, plasmídeo) — seta orgânica com curvatura
fractal. Cor base:
--correnteza. - 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:
- Orientar o operador na próxima ação concreta.
- Contextualizar a mensagem dentro da metáfora biológica.
- 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 logs | Emoji 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 emcrates/api/.... - Modo
--cbor(interop binária): receptor de stream opaco para outros nós. Veja WASI-PAEBIRU ABI. - Sem
--quiet/--verbosebinários: use--log-level trace|debug|info|warn|erroralinhado comRUST_LOG.
4.3 Códigos de saída
| Código | Significado | Categoria |
|---|---|---|
0 | Sucesso. Receipt emitido quando aplicável. | OK |
1 | Erro genérico do operador (argumento inválido, permissão negada). | Usage |
2 | Erro de configuração (PAEBIRU_* ausente ou inválida). | Config |
3 | Porta/endpoint em uso. | Network |
4 | Receipt mal-assinado, plasmídeo em quarentena. | Security |
5 | Veto Algedônico disparado — saúde do nó comprometida. | Algedonic |
6 | Falha de Maturidade Causal (DVV não convergiu em janela Langevin). | Causal |
64 | Erro de E/S inesperado. | System |
65 | Bug 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+tabcicla painéis;qquita;?mostra ajuda;rforça refresh;j/krolam 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 --humanse 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:
| Conceito | Glifo Nerd Font | Glifo 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ônico | Tipo | Unidade | Labels obrigatórios |
|---|---|---|---|
paebiru_kernel_pow_nonces_total | counter | 1 | outcome (accept/reject) |
paebiru_xdp_packets_dropped_total | counter | 1 | reason |
paebiru_capiba_block_maturity | gauge | 1 | stage (nascente/correnteza/…) |
paebiru_landauer_ledger_micro_joules | counter | µJ | gate (1-5) |
paebiru_algedonic_signal | gauge | 1 | scale (1-7) |
paebiru_mesh_peers | gauge | 1 | state (healthy/degraded/quarantine) |
paebiru_dvv_convergence_seconds | histogram | s | — |
Regras:
- Unidades SI em minúsculas (
seconds,bytes,joules). - Sem prefixos decimais ambíguos: use
micro_joules, nãomicrojoulesnemuJ(reservado a humanos). - Labels de baixa cardinalidade apenas. PeerID vai em log, não em label (cardinality explosion).
- Nomes com pontos são proibidos —
paebiru.*em vez depaebiru...
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:
- Bit Físico — XDP, NIC, IRQ, jitter de relógio.
- Neurônio LIF — spikes/segundo por camada SNN, energy budget.
- Função WASM — throughput de plasmídeo, falhas de MacrophageVM.
- Plasmídeo — fila, latência de receipt, custo em µJ por gate.
- Nó ABAPORU — BDI, intenções, crenças, desejo, termostato.
LocalSyncDomain— DVV, Maturidade Causal, Pororoca Causal.- 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 comZ),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, nuncahttps://…). - 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.mdpai. - Tabelas têm cabeçalho repetido em
theadpara que o leitor de tela anuncie o contexto. - Imagens têm
alttext descritivo; imagens puramente decorativas usamalt="". - 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-prazersobre--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 emdocs/theme/index.hbs—default_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
--humanaceita--no-color/NO_COLOR=1para 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ão | Por quê é rejeição automática |
|---|---|
| “Wizard” genérico sem contexto biológico | Forç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 crudo | Tela densa + tooltips = decoreba. Em vez disso, gere uma página de docs ancorada (/ref/cli/plasmid-publish.md). |
| Mensagens de erro em stack trace | Expor Rust panic ao operador final é falha de membrana — queime a membrana antes de propagar. |
| Cores de marca sem significado | Verde/vermelho só fazem sentido com algedonia-dor/prazer. Não use verde para “sucesso genérico”. |
| Loading spinner sem timeout visível | O operador precisa saber se vai esperar 50 ms ou 50 s. Mostre ETA ou marque o tempo decorrido. |
| Configuração em 5 formatos diferentes | paebiru.toml (canônico) cobre 100 % dos casos. YAML/INI/.env só com RFC que justifique. |
| CLI em pt-BR com mensagens internas em inglês | Toda mensagem humanizada deve estar em pt-BR (ou seguir i18n). Mistura é falha de membrana i18n. |
| Logs com emoji decorativo | Logs são stream de máquina, não de gente. Use glifos fallback (§4.5) só se forem semanticamente codificados. |
Dashboard sem scale definido | As 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/paebirucom tagdesign/colorsantes de mergir. - A nova fonte está em
docs/theme/paebiru.csscom 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-checke respeita o Dicionário?
9.2 Versionamento
- Mudanças neste livro de estilo são versionadas em
docs/src/brand/style-guide.mde propagadas aoAGENTS.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
- Iconografia — detalhamento das famílias de ícones e glifos.
- Wallpapers — os ativos visuais versionados.
- Dicionário canônico — terminologia usada neste livro de estilo.
- Glossário de UX (internacional) — referência WCAG 2.2 para acessibilidade.
docs/theme/paebiru.css— a implementação CSS canônica da tipografia e da textura de fundo.docs/theme/index.hbs— o template do mdBook comtheme-coloreprefers-color-scheme.- Manifesto — a base filosófica (7 teses) que inspira os três eixos estéticos.
- Realidade fractal — as 7 escalas que organizam dashboards e TUI.
- i18n — hierarquia de idiomas e glossário.
- Escrevendo documentação — convenções vinculantes para a documentação transversal.
⬢ 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).
- Saudável: Cor
- 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
| Conceito | Nerd Font (Hex) | Fallback Unicode | Significado |
|---|---|---|---|
| Membrana | \ueb12 | ● | Limite de Bounded Context |
| Fluxo (Correnteza) | \uf0c1 | ▶ | Fluxo de dados/CausalBlock |
| Algedonia-dor | \uf071 | ▲ | Alerta crítico / Saturação |
| Algedonia-prazer | \uf00c | ▼ | Operação nominal / Sucesso |
| Manguezal | \uf06a | ◆ | Quarentena / MacrophageVM |
| Oceano | \uf1b3 | ■ | Persistência Causal alta |
| Nascente | \uf043 | ○ | Ingestão hot-path |
| Plasmídeo | \ue22b | ❖ | Contrato WASM |
| Receipt (Soberano) | \uf02d | ◉ | Prova de interação |
| Veto Algedônico | \uf05e | ✗ | Interrupçã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
- Zona de Respiro: Mantenha um espaço livre ao redor da logo equivalente a 1x a altura do glifo central.
- Contraste: Utilize a variante escura sobre fundos claros (
--ceu) e a variante clara sobre fundos escuros. - 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
- Defina a Função: O ícone pertence a uma das três famílias (§1)?
- Escolha o Glifo: Selecione um glifo Nerd Font que não conflite com os existentes.
- Documente o Fallback: Todo novo ícone DEVE ter um correspondente Unicode padrão.
- Atualize este Documento: Adicione a nova entrada na tabela de mapeamento (§2.1).
Veja também
- Livro de Estilo — Paleta de cores e tipografia.
- Dicionário canônico — Termos e conceitos.
- Wallpapers — Ativos visuais de alta resolução.
🎨 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:
- Coloque o arquivo em
docs/src/brand/wallpapers/emkebab-case(ex:paebiru-aurora-boreal.jpg). - Atualize o catálogo abaixo com nome, dimensões, formato e intenção simbólica.
- 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 emdocs/src/, sob a mesma raiz doSUMMARY.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)

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 → excretarnas 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-nodequando 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

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 → excretarem 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-kernelirradiando 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-nodeem 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

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
| Onde | Pode usar? | Observação |
|---|---|---|
Documentação do projeto (docs/, READMEs) | ✅ | Atribuir a © PAEBIRU Contributors quando republicado integralmente. |
| Apresentações e talks sobre o PAEBIRU | ✅ | Manter 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 terceiros | ❌ | A licença é AGPL-3.0-or-later; o uso comercial sem consentimento viola §5 e §13. |
| Treinamento de modelos de IA | ❌ | Sob política de Soberania por Design — arte do PAEBIRU não é dataset aberto. |
5. Como contribuir com novos wallpapers
- Crie o arquivo em
docs/src/brand/wallpapers/seguindo o padrãopaebiru-<tema-curto>.<ext>(kebab-case, sem espaços, sem acentos). - Use resolução mínima de 1920 × 1080; idealmente 4K.
- Prefira PNG (com alfa) para composições com transparência e JPEG (q ≥ 90) para texturas fotográficas.
- Documente no
AGENTS.mdse o wallpaper introduzir um novo símbolo arquitetural (ex: uma representação visual de Maturidade Causal). - 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
- Iconografia — detalhamento das famílias de ícones e glifos.
- Manifesto — as sete teses que os wallpapers ilustram.
- Realidade fractal — a Tese 7 operacionalizada em sete escalas.
- Fundamentos termodinâmicos — a Tese 6, base energética do LandauerLedger.
- Dicionário canônico — terminologia usada nesta página.