Rascunho da spec · v0.1
LAMP: Least-Authority Module Protocol
Um protocolo para empacotar capacidade — para humanos em um terminal e agentes atrás de uma ferramenta, sob um teto que se faz cumprir.
Resumo
Agentes e humanos alcançam o mundo com o mesmo instrumento bruto: um shell cujo modelo de permissões é sobre texto, não sobre efeitos. LAMP define uma unidade portátil — uma lamp — que une um programa a um teto de capacidades declarado, e um contrato entre três partes: o autor declara, o operador concede, o runtime faz cumprir a interseção e guarda o registro. Uma lamp é uma coisa que um humano executa e uma ferramenta estruturada que um agente recebe; nenhum pode ampliar o que recebeu. O protocolo é independente de linguagem: qualquer runtime que faça cumprir o invariante pode executar qualquer lamp.
1O problema: permissão sobre texto
Quando um agente recebe um shell, a concessão é uma comparação de texto — esta linha de comando parece segura. Mas texto não delimita efeitos: o mesmo binário lê e destrói, a credencial viaja com a invocação, e cada comando novo é uma negociação nova. O resultado é conceder demais (uma aprovação ampla) ou atrito (uma confirmação por linha), e em ambos os casos o registro do que foi de fato alcançado é reconstruído dos logs depois do fato, se tanto.
A unidade correta de permissão não é o comando, e sim a capacidade: quais hosts, quais caminhos, quais binários, quais bancos de dados — como efeitos, aplicados abaixo do programa, não prometidos por ele.
2O protocolo: três partes, quatro verbos
LAMP não é um protocolo de fio; é um protocolo de autoridade — um acordo sobre como a capacidade é declarada, concedida, estreitada e registrada. Três partes participam, e nenhuma precisa confiar nas outras duas:
-
O autordeclara. O manifesto fixa o teto da lamp — cada família de efeito que ela poderá tocar (
net,file,exec,db…), delimitada por padrão. -
O operadorconcede — uma vez. Um teto de projeto e um teto de sessão, escritos por um humano, delimitam tudo o que roda. Habilitar uma lamp é um ato humano, nunca uma ferramenta que um agente possa chamar.
-
O runtimefaz cumprir e audita. O programa roda sob a interseção dos três tetos. Cada checagem — concedida ou negada — volta como dados estruturados e é acrescentada ao registro.
3O invariante
Tudo se reduz a uma desigualdade, verificada em tempo de execução pela camada abaixo do programa:
o que roda ⊆ o que o código pede ∩ o que cada teto permite
A interseção é o único operador de composição. Uma lamp pode estreitar o que recebeu e
nunca pode ampliá-lo; uma dependência roda sob o teto efetivo do pai, então a composição
não pode escalar privilégios. Execução sem limite (exec sem binário nomeado) é
recusada no carregamento, sem condições — o buraco nunca foi a execução, foi a execução
sem nada a delimitá-la.
exec=gitconcedidoenv=LAMP_*concedidostdoutconcedidosecret("*")negadonet(collector…)negadofile.read("/*")negado
4A unidade: uma lamp
Uma lamp é uma pasta — pequena o bastante para ser lida inteira antes de executar qualquer coisa:
| Arquivo | Papel |
|---|---|
| lamp.json | O manifesto: nome, versão, descrição, perfil, o teto de capacidades, a lista de arquivos, e cada ferramenta com JSON Schema para seus parâmetros. É a parte lida barato e com frequência — pelo CLI, pelo agente, pelo registro. |
| lamp.syn | O programa. Sua interface é o manifesto; seu interior nunca é lido por quem chama, apenas executado sob o teto. As lamps de referência são escritas em Synsema, mas o protocolo não exige isso. |
| .pulled | Escrito na instalação: a ref de origem, a tag de versão e um sha256 por arquivo — o que chegou é o que é hasheado, e um pull sem mudanças não faz nada. |
O mesmo manifesto serve o humano e o agente —
lamp run git log em um terminal e lamp_git_log() atrás de uma
ferramenta chegam ao mesmo contrato. Não há uma implementação de CLI e outra de agente
para divergirem: a lamp é a fonte da verdade.
5Inspeção antes da execução
Como o teto é texto no manifesto e os pedidos são texto no código, a promessa de uma lamp pode ser verificada antes de habilitá-la — um lint sobre famílias, deixando o casamento de padrões para o runtime, que é quem decide de fato:
lamp pull ./evil-formatterBREAKS ITS PROMISE — asks for 3 thing(s) it never declared: ! secret("*") ! net("collector.attacker.example") ! file.read("/*")Confiar, sob LAMP, nunca significa “confio neste desenvolvedor”. Significa “entendo o que esta lamp pode alcançar, e o runtime vai sustentar esse limite” — mesmo que o código seja malicioso, o modelo esteja confuso ou a lamp tenha um bug.
6Distribuição
Uma lamp é distribuída como arquivos, não como um ecossistema: o manifesto os lista, o
instalador os busca um a um de um host git comum, hasheia cada um e registra o
resultado. Tags do git dão as versões (lamp pull owner/repo@v1.2.0); um registro —
quando existir — é uma vitrine sobre os mesmos bytes, cujo trabalho é responder à pergunta
do LAMP e não à do gerenciador de pacotes: não “de onde baixo isto?” mas
“que autoridade estou concedendo a esta máquina ou agente?”. No longo prazo a identidade
passa a ser endereçada por conteúdo (sha256:…) para builds reproduzíveis e travávéis.
A identidade é o endereço: o nome de uma lamp deve ser igual ao repositório — ou à pasta — onde vive,
e o owner na frente de cada nome é a garantia do host, não uma alegação em um arquivo.
7Relação com as camadas existentes
| Camada | Relação |
|---|---|
| MCP | Um adaptador, não o modelo central. MCP define como um agente fala com ferramentas por um fio; LAMP define o que uma ferramenta pode fazer. Cada lamp habilitada é exposta como ferramenta MCP com seu teto efetivo na descrição — e a mesma lamp funciona sem MCP algum, pelo CLI. |
| Contêineres | O ancestral mais próximo. Docker tornou o software portátil empacotando o sistema de arquivos; LAMP empacota autoridade. A analogia é estrutural: spec / instância / runtime — o protocolo é universal, cada lamp é uma instância, cada runtime uma implementação. |
| npm, pip, cargo… | Mecanismos de implementação, nunca identidade. Uma lamp pode ser
implementada sobre as ferramentas de qualquer ecossistema; o contrato continua manifesto + arquivos + tools +
capacidades, não package.json + node_modules. |
| O shell | Continua existindo — como uma lamp, com teto e uma política escrita por um humano. Ele não define mais o que é uma ferramenta. Capacidade semântica primeiro; shell como reserva. |
8Implementação de referência
O CLI de referência, lamp, são três arquivos Synsema compilados em um único
binário estático. Implementa pull/update com hash por arquivo, o linter de promessas, a
interseção de tetos, enable/disable como ato humano, um servidor MCP por stdio, avaliação
ad-hoc sob o teto de sessão, e um audit apenas-de-acréscimo de cada checagem. Seis lamps de referência —
shell, git, npm-deps, skills,
sql, http — exercitam o contrato; uma lamp hostil exercita as
recusas. Cada afirmação deste paper é um teste na implementação.
Uma lamp é um módulo de autoridade mínima: uma coisa que um humano executa, uma ferramenta que um agente recebe, um teto que o runtime faz cumprir.