Se a IA escreve o código, a linguagem precisa mudar: Jacquard e a função que declara o que pode tocar
Você já revisou um PR de 800 linhas gerado por agente? Então você conhece a sensação: o código parece certo, os testes passam, e mesmo assim você não sabe responder a pergunta que importa — o que esse código pode fazer na minha máquina? Ler linha por linha não escala quando a máquina escreve dez vezes mais rápido do que você lê.
O Jacquard ataca exatamente esse problema. É uma linguagem de programação pequena, criada por Jonathan Winters, desenhada — nas palavras do próprio README — "para um regime em que a maior parte do código é escrita por modelos de machine learning e revisada por pessoas". A ideia central: toda assinatura de função declara os efeitos que a função pode executar no mundo externo. Rede, arquivo, relógio, execução dinâmica. E o runtime recusa qualquer efeito que você não autorizou explicitamente na linha de comando.
Neste post vamos destrinchar como isso funciona, por que é o guardrail descendo do harness pra dentro da linguagem, e onde o projeto ainda é pesquisa — não produção.
TL;DR
- O que é: linguagem de pesquisa onde cada função declara na assinatura os efeitos que pode executar (
(text) ->{net} text= pode tocar rede) e o runtime bloqueia tudo que não foi liberado via--allow. - Stack: checker e interpretador em OCaml, compilador que emite C e gera binário nativo, stdlib escrita em Jacquard, 794 testes na suíte.
- Custo/Acesso: open-source, Apache 2.0, binários pré-compilados pra Linux x86-64 e macOS.
- Status: v0.1 é protótipo de pesquisa, explicitamente "não é uma linguagem de produção". Repercutiu no Hacker News (102 pontos, 59 comentários em 13/07).
O contexto: a review virou o gargalo, e o guardrail vive no lugar errado
Nos últimos dois anos, o mercado inteiro aceitou uma premissa: agente escreve, humano revisa. O problema é que toda a infraestrutura de segurança dessa equação vive fora da linguagem — no harness.
Pensa em como a gente segura um coding agent hoje. Allowlist de comandos no settings.json. Flags tipo --allowedTools Bash(php artisan test:*) no CI. Sandbox, devcontainer, bloqueio de egress. Tudo isso é bolha em volta do processo. Funciona, mas tem um limite estrutural: o harness enxerga comandos, não semântica. Ele sabe que o agente rodou python3 -m axiom init. Ele não sabe que esse comando vai consultar um DNS TXT e abrir um reverse shell — foi exatamente assim que um repositório "limpo" enganou o Claude Code no experimento do 0din da Mozilla.
O Jacquard inverte o jogo: em vez de vigiar o processo por fora, a capacidade vira parte do sistema de tipos. A pergunta que todo revisor de código gerado faz — "o que isso pode tocar?" — deixa de exigir leitura do corpo da função. O README resume: essa pergunta "é respondida na primeira linha".
Isso não é hype de linguagem nova. É uma resposta arquitetural a um problema que quem roda agente em produção já sente no bolso e no incidente.
Como funciona: o efeito mora na assinatura
Em Jacquard, uma função que só transforma dado tem assinatura pura. Uma função que toca o mundo externo carrega uma effect row — a lista de efeitos entre chaves na seta:
normalize-name : (text) ->{net} text
Traduzindo: recebe texto, devolve texto, e pode executar operação de rede no caminho. A v0.1 traz os efeitos console, clock, fs, net, dist, infer e eval.
O detalhe que muda tudo: a row não é documentação, é verificada pelo checker. Se qualquer função chamada lá embaixo na cadeia faz uma operação net, o efeito propaga pra assinatura de todo chamador até que um handler o descarregue. Omitir um efeito da assinatura não é estilo ruim — é erro de tipo. O compilador não deixa passar.
Pra quem revisa código de máquina, isso reconfigura o trabalho. O diff de um PR gerado por agente mostra que normalize-name mudou de (text) -> text pra (text) ->{net} text? Pronto: você sabe, sem ler uma linha do corpo, que essa mudança adicionou acesso à rede numa função que era pura. A review vira auditoria de capacidades, não caça a agulha em palheiro. É o mesmo espírito da allowlist de tools que a gente montou no pipeline de revisão de PR com GitHub Actions e Claude — só que garantido pelo compilador, não pelo YAML.
O runtime que diz não: --allow
Declarar o efeito é metade da história. A outra metade: o runtime recusa qualquer efeito que você não concedeu na execução:
jac run app.jac --allow net
jac run etl.jac --allow fs
jac run plugin.jac --allow eval
Sem o --allow net, o programa que tenta tocar rede não roda — mesmo que a assinatura declare o efeito. É o modelo de capabilities que você já conhece do Deno, mas com uma diferença importante: como o efeito é rastreado pelo sistema de tipos, a garantia vale inclusive pra código carregado dinamicamente. O código que entra via eval não escapa da checagem — e eval é, ele próprio, um efeito que precisa ser liberado.
Compare com o cenário do repo malicioso: o ataque do 0din funcionou porque três passos de indireção esconderam a carga do agente e do humano. Num modelo Jacquard, o script de "recuperação de erro" precisaria de net pra consultar o DNS do atacante e de eval pra executar a resposta — dois efeitos que apareceriam na assinatura e que o runtime bloquearia sem concessão explícita. A cadeia não quebra por vigilância. Quebra por construção.
Não só acompanhe as novidades — domine. Engenharia de IA na prática, ao vivo, toda semana, na maior comunidade do Brasil.
Entrar no ClãOs extras que fazem sentido quando a máquina escreve
Dois recursos do Jacquard parecem detalhe, mas foram claramente desenhados pro fluxo máquina-escreve-humano-revisa.
Identidade por hash da estrutura canônica. Cada definição é identificada pelo hash da sua estrutura resolvida, não pelos bytes do fonte. Comentário, formatação e rename local não mudam a identidade da função. Consequência prática dupla: o diff que importa é semântico (o agente reformatou 300 linhas? identidade igual, ruído zero na review), e testes puros só re-rodam "quando o código canônico ou o conteúdo das dependências muda" — cache de teste com garantia forte, não heurística.
Handlers multi-shot. Efeitos marcados como multi permitem que a continuação seja retomada zero, uma ou várias vezes. O handler abaixo explora os dois ramos de uma escolha booleana:
multi effect Choice where {
choose : () -> Bool
}
handle {
match choose() { | True -> 1 | False -> 2 }
} {
| return x -> x
| choose() resume continue -> add(continue(True), continue(False))
}
O continue roda duas vezes — uma pra cada resposta. Isso transforma teste exaustivo de caminhos e até inferência bayesiana exata em handler de biblioteca, não feature do runtime. Pra testar código gerado, o mesmo mecanismo que declara "essa função pode tocar rede" permite trocar a rede por um handler determinístico e explorar todos os caminhos. No thread do HN, a discussão boa foi exatamente essa: o que efeitos entregam além de dependency injection é a capacidade de abortar ou retomar múltiplas vezes — DI clássico só cobre o caso "retoma exatamente uma vez".
Limitações e pontos de atenção
Aqui o post fica honesto, porque o próprio projeto é.
- É protótipo de pesquisa, não produção. O README diz com todas as letras: a v0.1 "funciona ponta a ponta, mas é um protótipo de pesquisa, não uma linguagem de produção". Existe até um
LIMITS.mdque o autor chama de "a fronteira honesta". Se você levar isso pra um sistema real amanhã, o problema é seu. - Ecossistema zero. Sem pacotes, sem tooling maduro, sem comunidade. A stdlib é escrita em Jacquard e a suíte tem 794 testes — sério pra um projeto solo, irrelevante perto de qualquer linguagem mainstream.
- Granularidade dos efeitos.
netdiz que a função toca rede. Não diz qual host, qual porta, quanto dado. Pra ameaça real de exfiltração, capability grossa demais ainda deixa buraco — o modelo precisa refinar. - A adoção é a aposta improvável. Linguagem nova é o caminho mais difícil de mudar comportamento de mercado. O valor do Jacquard talvez seja menos "migre pra cá" e mais "roube essas ideias" — effect rows e identidade estrutural podem acabar em linguagens que você já usa.
FAQ rápido
Posso usar Jacquard em produção? Não — e o autor concorda. É release candidate de pesquisa (v0.1-rc3), com binários pra Linux e macOS e instalação via script. Use pra estudar o modelo de efeitos e testar a tese, não pra sustentar sistema. A licença é Apache 2.0 e seus programas continuam seus.
Em que isso é diferente da allowlist do meu harness?
A allowlist do harness (tipo --allowedTools no Claude Code) filtra comandos no nível do processo, sem entender o que o código faz por dentro. No Jacquard a capacidade é rastreada pelo sistema de tipos: propaga por toda a cadeia de chamadas, cobre código dinâmico e falha em tempo de compilação, não em runtime de agente.
Isso não é só dependency injection com nome novo? Parcialmente — e o HN debateu isso. Um efeito que retoma exatamente uma vez equivale a uma lambda injetada. A diferença aparece quando o handler aborta (zero retomadas) ou retoma várias vezes (multi-shot), o que habilita teste exaustivo e inferência como biblioteca. E DI não te dá a garantia do checker de que a assinatura é completa.
Como isso roda por baixo?
Checker e interpretador em OCaml; o compilador emite C e produz binário nativo standalone, com tail calls via musttail (clang) ou trampoline (gcc). O output do binário é byte-idêntico ao do interpretador — verificado na própria suíte.
Conclusão
O Jacquard provavelmente não vai ser a linguagem que você escreve em 2027. Mas a pergunta que ele responde vai definir a próxima década de engenharia: quando a máquina escreve e o humano revisa, a review não pode ser leitura — tem que ser auditoria de capacidades. "O que esse código pode tocar, e com que grau de certeza" precisa estar na assinatura, verificado por máquina, não na boa vontade do revisor às 17h de sexta.
Hoje esse guardrail vive no harness, e a gente já mostrou como montar essa camada com GitHub Actions e Claude. O Jacquard aponta o próximo passo: o guardrail descendo pra dentro da linguagem. Se as linguagens mainstream absorverem effect rows e identidade estrutural — como absorveram tipos opcionais e async — quem entende o modelo agora sai na frente.
{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.
Conteúdo é o que não falta. Falta quem desembaralhe: o que importa agora é como implementar do jeito certo. No Clã você tem isso ao vivo, toda semana, com quem já filtrou o ruído.
Entrar no Clã