* spec: delegacao de agentes + a face A2A (o executor que falta e o Card como Kind)
O modelo de delegacao JA ESTA no kernel, com as duas pontas do aperto de mao:
AgentSpec.team_members (quem pode delegar) e DelegationTargetFor (quem aceita,
com format/use_when/typical_seconds). O que NAO existe e o executor —
`delegate_to` aparece EXCLUSIVAMENTE em kernel/models.py, sem implementacao,
sem teste, sem tool. Capacidade existe, porta nao.
Esta spec implementa o executor e a face A2A nas duas direcoes, sem inventar
protocolo:
• O PROTOCOLO NAO E UM KIND (erro de categoria). O AGENT CARD e: documento
versionado, com schema, descrevendo identidade e capacidade. Vira o Kind
RemoteAgent.
• DOIS Kinds, porque os campos sao DISJUNTOS: Agent declara comportamento
(instruction/model/tools — o DNA compoe e executa); RemoteAgent descreve e
aponta (supported_interfaces/skills/securitySchemes — o DNA localiza e
chama). Um Kind so validaria absurdo, e additionalProperties:false nao sabe
dizer 'estes campos OU aqueles'.
• O QUE UNE OS DOIS e um roster DERIVADO — 'todo documento que declara
delegation_target_for e cuja allowlist me inclui' — atravessando os dois
Kinds. Lista mantida a mao fica cega e verde; a licao de 29/07 aplicada no
desenho, nao no codigo.
• A DIRECAO DE SAIDA E `emit`: projetar um Agent num Agent Card servido no
well-known. Alvo de emit, nao mecanismo novo.
Tres regras de seguranca que nascem com o desenho, porque um RemoteAgent e por
construcao um canal de exfiltracao: data_scope obrigatorio e explicito (resposta
implicita significa 'tudo'); NUNCA repassar o token do usuario (a credencial e
do workspace — senao cada remoto vira impersonacao completa contra o nosso
proprio MCP); e allowlist DUPLA, as duas pontas sempre.
Par no dna-cloud: os documentos (supervisor/conversor), o console e o canvas.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Work-Item: Story/s-stamp-dated-spec-fields
Co-Authored-By: dna-sdlc[bot] <302582850+dna-sdlc[bot]@users.noreply.github.com>
* plan: implementacao da delegacao + face A2A (SDK, sete tarefas)
Sete tarefas TDD sobre a spec 2026-07-30-a2a-delegation-design.md:
1. o Kind RemoteAgent (descritor + entry point + as guardas de docs)
2. a politica PURA — allowlist dupla + roster derivado (4 mutantes)
3. o executor de delegate_to, caminho local + parse por format
4. o transporte A2A — escopo antes do envio, credencial do workspace (5 mutantes)
5. entrada: Card de terceiro vira RemoteAgent INERTE
6. saida: projetar um Agent num Card (emit)
7. a cadeia de release (tres lugares da versao, indice SIMPLE, lockstep)
AS TRES DECISOES ABERTAS DA SPEC ficam como PREMISSAS DECLARADAS no topo, para
serem contestadas em revisao e nao descobertas em producao: assinatura vira
signature_state tri-estado (verificacao fora da v1, mas a ausencia dela fica
LEGIVEL); data_scope e por Kind (sensibilidade entra depois, aditivo); e o Card
de saida nao e servido por esta spec — o SDK entrega a PROJECAO, e quem serve em
qual path e decisao de deployment, o que dissolve a pergunta em vez de
responde-la errado.
POLITICA E EXECUTOR EM ARQUIVOS SEPARADOS de proposito: a politica e a fronteira
de autorizacao e merece ser lida sozinha. Em 29/07 a licao foi que a politica
pura estava certa nos treze defeitos e o erro estava sempre na montagem em
volta — manter a parte correta pequena e o que torna isso possivel.
UMA ARESTA DEIXADA VISIVEL: a nota do Task 2 Step 3 registra que a assinatura de
may_delegate no teste nao carrega o nome do delegador, com a correcao escrita.
Um plano que finge nao ter arestas ensina a confiar nele sem ler.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Work-Item: Story/s-stamp-dated-spec-fields
Co-Authored-By: dna-sdlc[bot] <302582850+dna-sdlc[bot]@users.noreply.github.com>
* feat(a2a): delegacao de agentes + a face A2A — as seis tarefas do plano
O modelo de delegacao JA ESTAVA no kernel, nas duas pontas (AgentSpec.team_members
e DelegationTargetFor), e NUNCA teve executor: delegate_to aparecia so em
models.py. Capacidade existe, porta nao. Isto e a porta, mais o Agent Card do A2A
como Kind.
1. RemoteAgent — o Card como Kind. Schema FECHADO (securitySchemes diz COMO
autenticar; credencial nunca e documento), data_scope OBRIGATORIO (um remoto
e por construcao canal de exfiltracao, e escopo implicito significa 'tudo'),
signature_state tri-estado ('nao verificado' e diferente de 'nao assinado').
13 testes.
2. A politica PURA — allowlist DUPLA e roster DERIVADO atravessando os dois
Kinds. 12 testes, 4 mutantes mortos.
3. O executor — recusa nomeada em todo caminho. 10 testes.
4. O transporte A2A — escopo checado ANTES do envio, credencial do WORKSPACE
jamais do usuario (asserido contra a ASSINATURA da funcao).
5. Entrada — um Card de terceiro nasce INERTE (approved=False, sem caminho para
True). 8 testes.
6. Saida — projetar um Agent num Card, via emit. skills DERIVADOS das tools.
5 testes.
TRES DEFEITOS DO PLANO que a execucao expos, todos corrigidos no proprio arquivo
do plano em vez de silenciados:
• O envelope do descritor estava ACHATADO e a forma nao existe no codebase —
TypedKindDefinition.from_raw exige kind: KindDefinition com tudo sob spec:.
Eu criei o SourceArtifact nesta mesma sessao e ainda escrevi o envelope errado
de memoria.
• O comando de teste (`python -m pytest`) nao funciona: o interpretador
ambiente nao tem pytest, precisa de `uv run`.
• may_delegate de tres argumentos era indecidivel — a aresta deixada VISIVEL no
plano de proposito, e que funcionou: o implementador achou, consertou pela
prescricao, e avisou.
Tambem: um falso positivo real do gen_data_model_docs.py (inferia
RemoteAgent.skills -> Skill por singularizacao) entrou no INFERENCE_DENYLIST com
a razao escrita, no mesmo padrao das entradas que ja existiam.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Work-Item: Story/s-stamp-dated-spec-fields
Co-Authored-By: dna-sdlc[bot] <302582850+dna-sdlc[bot]@users.noreply.github.com>
* fix(a2a): remover o parametro `token` que meu commit anterior capturou no meio de um mutante
Defeito de PROCESSO meu, nao do codigo. Eu commitei 036a461d enquanto o agente
da Task 4 ainda trabalhava na mesma arvore — depois de instruir todos os agentes
a NAO commitar exatamente para evitar isso. O snapshot pegou a2a_transport.py no
meio do mutante #5 (`token: str | None = None` adicionado a call_remote), que o
agente reverteria segundos depois.
O parametro e precisamente a brecha que o teste existe para fechar: um caminho
por onde o bearer do usuario atravessaria a fronteira, fazendo de cada agente
remoto uma impersonacao completa dele contra o nosso proprio MCP.
POR QUE A SUITE NAO PEGOU: pytest roda contra a ARVORE, nao contra o HEAD.
Quando rodei os 4593 testes, o agente ja havia revertido o mutante na arvore —
entao a arvore estava sa e o COMMIT estava doente. Verde num estado que nao era
o commitado.
E a mesma familia de tudo que este dia produziu: um snapshot tirado no momento
errado, capturando estado inconsistente, com a verificacao apontada para o lugar
certo mas no instante errado. A licao que fica e concreta: nao commitar enquanto
ha agente escrevendo na arvore — e verificar o COMMIT, nao so a arvore.
Achado pelo relato do agente, que preferiu FLAGAR em vez de consertar-e-commitar
por conta. Se ele tivesse silenciosamente consertado, eu nunca saberia que o
commit anterior estava furado.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Work-Item: Story/s-stamp-dated-spec-fields
Co-Authored-By: dna-sdlc[bot] <302582850+dna-sdlc[bot]@users.noreply.github.com>
* chore(release): 0.38.0 — delegacao de agentes + a face A2A
Minor, porque a feature e nova: o executor de delegate_to (que existia como
vocabulario no kernel e nunca como implementacao), o Kind RemoteAgent (o Agent
Card do A2A como documento), e as duas direcoes da face A2A.
Os TRES lugares da versao, mais o comentario que repete o teto:
• packages/sdk-py/pyproject.toml → 0.38.0
• packages/cli/pyproject.toml → 0.38.0
• o teto interno do CLI → dna-sdk>=0.38,<0.39 (a dep E o comentario)
Minor move o teto — foi por isso que o script conferiu DUAS ocorrencias antes de
trocar: o comentario que repete a restricao ja ficou obsoleto antes, e um teto
que diverge do comentario e uma mentira que compila.
Portao verificado por inteiro, nao por amostra: 4593 testes, brand_guard
(conteudo + identidade dos commits), gitleaks (1062 commits, zero vazamento), e
as tres guardas derivadas de docs (kinds/MER/cobertura de prosa) limpas.
A UNICA vermelha da suite local (test_imported_claude_fact_is_recallable_by_
paraphrase) NAO e portao: o CI instala '.[dev,runtime]' sem o extra embed-onnx,
entao o importorskip a PULA lá. Ela falha so em maquina com fastembed instalado,
e e assercao de qualidade de ranking semantico. Dito com precisao: nao provei que
passava em main (nao reproduzi o ambiente), provei que nossas mudancas nao
alcancam esse caminho e que o portao nao a inclui.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Work-Item: Story/s-stamp-dated-spec-fields
Co-Authored-By: dna-sdlc[bot] <302582850+dna-sdlc[bot]@users.noreply.github.com>
---------
Co-authored-by: Jefferson Barnabé <3090620+ruinosus@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: dna-sdlc[bot] <302582850+dna-sdlc[bot]@users.noreply.github.com>