Ecossistema de Agentes
Um loop de governança em camadas. Cada componente possui exatamente uma preocupação; eles se acoplam apenas por meio de contratos JSON tipados, nunca importando as máquinas de estado uns dos outros.
O objetivo imutável $shame é shame-deterministic-instruction-obedience-v1
(skills/shame/immutable_goal.json): tornar impossível para agentes de projeto ignorar instruções explícitas, convertendo obediência a instruções e relatórios de conclusão em contratos tipados validados por pydantic, gates de extensão determinísticos e avaliações agentivas retidas. Prosa é apenas exibição e não pode decidir sucesso. Cada membro do ecossistema nomeado abaixo DEVE preservar esse objetivo em seu limite.
O grafo
Renderizado com $create-svg (scene.yml é a fonte;regenerar com
skills/create-svg/run.sh render skills/agent-ecosystem/scene.yml skills/agent-ecosystem/ecosystem.svg).
O manifesto de associação legível por máquina é members.json (validado por scripts/membership.py validate; avaliação retida o mantém atualizado).
Os gera, o SVG acima e o bloco mermaid abaixo são ilustrações NÃO NORMATIVAS;
a tabela de propriedade e as seções ## Ecosystem dos membros são a topologia normativa.
flowchart TB
subgraph SHAPE[Modelagem da geração]
PONY[ponytail\nEscada YAGNI, sem recibos]
end
subgraph TURN[Camada de turno - Sessão Pi]
SHAME[extensão shame\npi.agent_status.v1\nvalidar, compilar, engolir]
TRIAGE[triage-error\nvocabulário de falhas\ncódigo, causa, próximo_comando]
end
subgraph WORK[Camada de fluxo de trabalho]
ASK[ask\ncompila intenção para contratos DAG]
TAU[tau\nexecuta DAGs, é dono da aceitação\nrecibos de nó tipados, goal_hash]
end
subgraph OPS[Camada de operações]
WD[project-watchdog\ndespacho cron, leases,
gates de prova, recibos de tick]
HERDR[ponte ops-herdr\ncaixa de entrada, quiescência,
cartas mortas TTL]
end
MEM[(Memory\nexemplos de treinamento,
resoluções de triagem,
conhecimento do projeto)]
PONY -.-> SHAME
SHAME -->|failed.triage.code| TRIAGE
SHAME -->|comandos compilados needs_*| ASK
ASK -->|tau.dag_contract.v1| TAU
TAU -->|recibos de nó / handoff v2 carrega status| SHAME
WD -->|ticket_repair via ask| ASK
WD -->|lê vereditos| TAU
HERDR -->|códigos de triagem de cartas mortas| TRIAGE
SHAME -->|exemplos rotulados| MEM
TRIAGE -->|códigos cunhados| MEM
TAU -->|exportação pós-execução de recibos de nó ruins| MEM
Tabela de propriedade
| Componente | Possui | Emite | Consome | DEVE para o objetivo imutável $shame |
|---|---|---|---|---|
| agentes de projeto | obediência a instruções no limite do turno | relatórios pi.agent_status.v1 | instruções do operador, resultados de ferramentas, recibos | DEVE reportar trabalho protegido como dados de status tipados, usar continuing.not_done[].next_command para trabalho inacabado executável por agente, e nunca tratar prosa/commits/opinião de revisor como prova de conclusão. |
| triage-error | vocabulário de falhas (failure_codes.json) | {código, causa, próximo_comando} | texto de erro bruto de qualquer camada | DEVE fazer um sinal bruto mapear para um código de catálogo ou cunhado; rótulos terminais vagos não podem se tornar decisões válidas. |
| shame | status do turno (pi.agent_status.v1) e shame.immutable_goal.v1 | objetos de status, objetivo imutável, exemplos de treinamento | códigos de triagem, rótulos humanos | DEVE manter a verdade do status validada por pydantic, prosa-apenas-exibição e com gate de avaliação. |
| extensão lazy-report-shame-shame-shame | aplicação de message_end do Pi | pacotes de rejeição, status renderizado, comandos de acompanhamento | JSON de status final, ledgers de continuação | DEVE rejeitar JSON de status ausente/inválido, remover prosa de status escrita pelo modelo, renderizar a partir de dados validados e enfileirar comandos de continuação/escalonamento compilados. |
| status-json-check.mjs | extração de status final e invocação de validador | resultado do verificador com objeto de status validado | texto do assistente | DEVE não decidir validade de status com regex, cabeçalhos de prosa, markdown, HTML ou julgamento de LLM. |
| agent_status_schema.py | legalidade de status pydantic | passagem/falha de análise | JSON de status final | DEVE tornar estados de status inválidos irrepresentáveis com extra=forbid, cargas de estado tipadas, códigos de triagem canônicos, e not_done apenas em continuing. |
| compile-status-command.mjs | compilação tipada de status para comando | comando de acompanhamento exato ou nenhum comando | objeto de status validado por pydantic | DEVE compilar cargas continuing/needs_* mecanicamente e compilar estados terminais/humanos para nenhum comando automático. |
| agentic-evals | prova de regressão retida | relatórios de prontidão | fixtures e comandos | DEVE falhar se a política de status por regex/prosa retornar ou se invariantes de status pydantic forem enfraquecidas. |
| ask | compilação de intenção para DAG | tau.dag_contract.v1, pacotes de recuperação | cargas de escalonamento de status | DEVE consumir cargas tipadas needs_* em vez de prosa de escalonamento informal. |
| tau | execução de DAG e aceitação | recibos de nó, tau.agent_handoff.v1/v2, hashes de objetivo | contratos DAG, objetos de status embutidos | DEVE possuir hashes de objetivo imutáveis e recibos de aceitação tipados; prosa de revisor não pode substituir aceitação. |
| project-watchdog | despacho agendado | recibos de tick, gates de prova, locks, ledgers de continuação | tickets do GitHub, vereditos do tau | DEVE expor trabalho aberto legível por máquina para que done possa falhar enquanto tickets/gates/próximos passos permanecem não resolvidos. |
| ops-herdr | transporte entre sessões | registros de caixa de entrada, cartas mortas | códigos de triagem | DEVE carregar falha/estado entre sessões como registros de caixa de entrada ou cartas mortas com códigos de triagem. |
| ponytail | minimalismo de geração | comentários de dívida ponytail: (não recibos) | nada do mundo de recibos | DEVE não substituir requisitos de status, recibo, prova ou avaliação. |
| Memory | recall | respostas de leitura de volta de armazenamento/recall (não recibos de envelope; recalls são observações, nunca embrulhadas) | tudo durável | DEVE armazenar exemplos do shame, resoluções de triagem e conhecimento do projeto com leitura de volta; recalls são observações, não recibos de conclusão. |
| agent-ecosystem | propriedade de componentes e limites de recibos | validação pi.receipt_envelope.v1 | cargas de limite | DEVE publicar o mapa de propriedade e exigir embrulho de envelope em fronteiras que alteram autoridade. |
| goal-helper | forma de objetivo centrada em prova | prompt/checklist de objetivo imutável | texto de objetivo humano | DEVE manter o sucesso vinculado à prova primária, critérios de conclusão, escopo permitido, deriva proibida, orçamento de repetição e condição de parada. |
pi.receipt_envelope.v1 - o envelope de limite
Embrulhe uma carga no envelope APENAS em fronteiras que alteram autoridade: despacho, handoff, aceitação, escalonamento, fechamento, falha durável. Objetos internos permanecem desembrulhados (decisão YAGNI revisada: sem barramento de eventos universal, sem envelope em todo artefato).
{
"schema": "pi.receipt_envelope.v1",
"receipt_id": "id-estável",
"payload_schema": "pi.agent_status.v1",
"producer": "shame",
"emitted_at": "RFC3339",
"goal_hash": "sha256:<64hex> (opcional)",
"parent_refs": [
{"receipt_id": "id", "expected_schema": "s", "expected_producer": "p", "digest": "sha256:<64hex> (opcional)"}
],
"triage_code": "código de catálogo ou cunhado (opcional)",
"payload": {}
}
Validar com:
skills/agent-ecosystem/run.sh validate <envelope.json>
echo '{...}' | skills/agent-ecosystem/run.sh validate -
Regras aplicadas por scripts/receipt_envelope.py (pydantic, extra=forbid):
triage_code, quando presente, deve ser um código de catálogo do triage-error ou um código cunhado*_unclassified_<8hex>- mesma regra quepi.agent_status.v1.failure.goal_hasheparent_refs[].digestdevem sersha256:+ 64 hex minúsculos.parent_refsexigemgoal_hash: uma aresta de evidência sem um objetivo compartilhado não é confiável e falha na validação.- Pydantic prova ESTRUTURA apenas. RESOLUÇÃO de referência é uma etapa
separada do lado do consumidor com quatro verificações obrigatórias: o recibo referenciado existe;
seu schema é igual a
expected_schema; seu produtor é igual aexpected_producer; eresolved_parent.goal_hash == envelope.goal_hash(um hash presente não é um objetivo compartilhado até ser comparado). A verificação de digest é aplicada quandodigestestá definido. Um envelope estruturalmente válido ainda não é um confiável. payload.schemaé OBRIGATÓRIO em toda carga embrulhada e deve ser igual aopayload_schemado envelope; uma carga anônima falha na validação.- Mudanças no conjunto de campos de qualquer schema
extra=forbidsão quebras por construção; elas exigem uma nova versão de schema, nunca uma edição no local.
Convenções de campo JSON compartilhadas
Os campos abaixo são a superfície compartilhada real. Um componente "compartilha" um campo quando emite ou valida o mesmo nome, forma e semântica que o proprietário.
| Campo | Forma | Proprietário | Compartilhado por |
|---|---|---|---|
schema | id versionado, ex. pi.agent_status.v1 | cada proprietário de schema | todo objeto de contrato; bumps de versão são aditivos-ou-novo-nome |
code (triagem) | entrada de catálogo ou <prefixo>_unclassified_<8hex> | triage-error | shame failure.triage.code, envelope triage_code, cartas mortas do herdr, pacotes de recuperação do ask |
cause / next_command | string simples / comando executável exato | triage-error | todo consumidor de uma classificação de triagem; next_command também é o campo continuing keep-going do shame |
goal_hash | sha256: + 64 hex minúsculos | tau (pacote de objetivo imutável) | status do shame (opcional), envelope (opcional), todo recibo de nó do tau |
verified[] | pares {command, result} | shame | prova de estado done em todo lugar que um objeto de status é embutido |
proof[] | caminhos/URLs/ids concretos; caminhos locais em pi.agent_status.v1 devem existir antes de done passar | shame | objetos de status; gates de prova do watchdog nomeiam os mesmos artefatos |
parent_refs[] | {receipt_id, expected_schema, expected_producer, digest?} | envelope agent-ecosystem | evidência de escalonamento (substitui caminhos ad hoc em needs_webgpt) |
producer / receipt_id / emitted_at | string / id estável / RFC3339 | envelope agent-ecosystem | qualquer recibo embrulhado em limite |
payload_schema | id versionado; deve ser igual a payload.schema quando a carga declara um | envelope agent-ecosystem | qualquer recibo embrulhado em limite |
| vereditos terminais | PASS FAIL BLOCKED NEEDS_ATTENTION | tau | ask se junta, gates de prova do watchdog, monitores de fluxo |
recoverable / not_this | bool / lista de exclusão | catálogo do triage-error | consumidores decidindo repetir vs escalonar |
Convenções do triage-error (normativas aqui, implementadas lá)
- Um sinal bruto mapeia para UM
{código, causa, próximo_comando}; um código genérico em um limite de camada é um bug, não uma classificação. - Entradas de catálogo vivem em
skills/triage-error/failure_codes.jsoncom{código, camada, match[], causa, próximo_comando, recuperável, not_this[]}. A correspondência é determinística: a normalização é exatamente" ".join(texto.lower().split())(minúsculas, todas as sequências de whitespace colapsadas para espaços simples, pontas cortadas); uma entrada corresponde quando QUALQUER um de seus tokensmatch[](também em minúsculas) é uma substring do sinal normalizado; quando--layeré fornecido, entradas com umalayerdiferente são puladas; a PRIMEIRA entrada correspondente na ordem do arquivo vence. Nunca regex, nunca julgamento de LLM. Proibido como classificações terminais (são sintomas, não causas, e devem ser re-tiradas do sinal subjacente):NEEDS_ATTENTION,BLOCKED,browser_handler_timeout,unknown_error,generic_failure, e qualquer palavra de veredito terminal simples. - Sinais não correspondentes cunham
<camada-ou-desconhecido>_unclassified_<8hex>onde os 8 caracteres hex são os primeiros 8 de sha256 sobre o texto do sinal normalizado, então o mesmo sinal sempre cunha o mesmo código. Cunhar abre o ticket + loop de agente-avaliação + memória. Limiar de recorrência: a SEGUNDA observação do mesmo código cunhado aciona promoção ou aliasing. Representação de alias: um mapaaliasesde nível superior no arquivo de catálogo mapeia código cunhado -> código canônico; porque cunhar é determinístico sobre o sinal normalizado, um sinal recorrente cunha novamente o mesmo código e o classificador o resolve através do mapa para a entrada canônica (registrada comoaliased_from); o código cunhado nunca é uma segunda identidade canônica. Os efeitos colaterais de ticket/avaliação/memória são idempotentes por código cunhado (chaveados pela string do código). - Todo componente do ecossistema que nomeia uma falha usa um código de catálogo ou cunhado. Tanto validadores pydantic (schema de status, envelope) aplicam isso em tempo de análise, então um rótulo ambíguo não pode existir em um objeto válido.
Decisões de design (da revisão externa)
- Rigor se aplica a DECISÕES, não a observações. Mantenha evidência bruta
permissiva; mantenha resultados aceitos rigorosos. Uma observação tipada
unknowné legal; uma decisão ambígua não é. - Códigos cunhados
*_unclassified_*têm um ciclo de vida provisório: promova para o catálogo ou crie alias para um código existente quando recorrerem; nunca os deixe proliferar. - Mudanças de schema são aditivas; mudanças de forma que quebram recebem uma nova versão
(padrão
tau.agent_handoff.v2), nunca edições no local. - Não construir: um barramento de eventos de governança universal; recibos para comentários do ponytail, recalls do Memory ou repetições internas.
Associação
Uma skill ou extensão se junta ao ecossistema adicionando uma seção ## Ecosystem ao
seu SKILL.md nomeando: quais schemas produz, quais consome e quais
eventos de limite embrulha no envelope. Membros atuais: shame, triage-error,
tau, ask, project-watchdog, ops-herdr. Ponytail é adjacente por design.