Pular para o conteúdo principal

Artefatos

Um artefato é a saída estruturada e validada de um agente. Concretamente: um evento artifact.<tipo> no log, com o payload validado contra um schema fechado antes de ser gravado.

Não existe tabela de artefatos. A validação acontece num lugar só — Engine.Harness.ArtifactSchemas — e um campo obrigatório ausente reprova a emissão, em vez de gravar um artefato pela metade.

Quem pode emitir o quê​

Esta é a distinção mais importante da página, e é fácil não vê-la:

origemsignificado
ferramentao modelo decide emitir, chamando emit_artifact
servidoro código emite quando o desfecho acontece; o modelo não escolhe

Só três tipos são emitíveis por ferramenta: note, business_rule e decision_record. Todo o resto é emitido pelo servidor.

O motivo é o mesmo em todos os casos: quando o artefato é o registro de um desfecho, deixar o modelo escolher se o emite é deixá-lo omiti-lo. Um DevAgent que desiste não deveria poder decidir não registrar que desistiu.

O tipo de sessão não filtra artefato nenhum. A RN-097 deu à sessão um kind (consultiva | criativa) e pôs uma guarda no append de eventos, mas ela alcança um tipo — execution.activated — e nenhum artefato é ele. Uma sessão consultiva grava artifact.business_rule do mesmo jeito: o que ela não faz é entrar em execução. Quem chega à regra do tipo tende a supor o contrário, e a suposição errada aqui apagaria o registro de uma conversa inteira.

O ESTADO da sessão filtra por ator. Desde a RN-581 uma sessão closed/closed_abnormally recusa conversa com 409, e "conversa" inclui todo evento cujo ator é um agente conversacional — então um artifact.* do Criativo, do PO, do Arquiteto, do Dev Lead, do UX Designer, do Staff ou do Infra Lead não entra mais numa sessão fechada, enquanto os mesmos tipos de artefato emitidos pelo Psicólogo, que roda sobre a sessão fechada, entram. Quem decide nunca é o tipo; é o ator.

Os schemas​

note — ferramenta​

campoobrigatório
title✅
body✅

business_rule — ferramenta​

campoobrigatório
title✅
description✅
origin✅ — lista não vazia

origin referencia os eventos da conversa que originaram a regra. Lista vazia reprova: ela é a rastreabilidade da regra até onde foi enunciada, e sem ela a regra vira uma afirmação sem procedência.

:::caution O modelo precisa SABER os nomes dos campos A descrição da ferramenta emit_artifact é gerada a partir destes schemas (ArtifactSchemas.required/1) e nomeia cada campo obrigatório, em inglês, com um exemplo preenchido.

Não é preciosismo: a descrição anterior dizia apenas "emite um artefato tipado" e listava os tipos. Numa execução real o modelo — conversando em português — chutou titulo/descricao/comportamento, e as quatro regras de negócio daquela conversa foram rejeitadas em silêncio. origin como texto livre também reprova: tem de ser lista, e a descrição diz isso com todas as letras (RN-061). :::

decision_record — ferramenta​

campoobrigatório
context✅
options✅ — lista
choice✅
consequences✅

O "ADR resumido" que qualquer um dos seis agentes conversacionais pode emitir — Criativo, PO, Arquiteto, Dev Lead, UX Designer e Staff carregam emit_artifact com este tipo (RN-505). Sem validação entre campos de propósito: choice não precisa coincidir literalmente com uma das options — texto livre é mais robusto, e o schema genérico só confere a presença das chaves, a mesma régua de note/business_rule.

Ele reusa o padrão genérico em vez do dedicado (artifact.project_image/artifact.c4_diagram, versionado, schema TS próprio, rota HTTP própria): uma decisão é append-only por natureza, não um valor "vigente" que se substitui. Ele é deliberadamente distinto de open_adr_pr (só do Arquiteto, commita um arquivo real em docs/adr/*.md e abre uma PR real com aprovação humana obrigatória) — os dois coexistem para escalas diferentes de decisão: decision_record é sem atrito, pesquisável no log da sessão, para qualquer decisão relevante; open_adr_pr é para quando a decisão é grande o bastante para virar documento real do repositório.

open_question — ferramenta própria​

campoobrigatório
questionId✅ — uuid, gerado pela ferramenta
pergunta✅ — até 500 caracteres
afeta✅ — {regras, historias, tarefas}, listas de ids
sugestaoopcional — até 300 caracteres

Uma dúvida que um agente deixa para o usuário (ADR 0214, RN-862). Não é emitível por emit_artifact: só o Criativo, o PO, o Arquiteto e o Dev Lead a emitem, pela ferramenta própria declare_open_question, que grava também autor e sessionId. A api a fecha com open_question.answered.

product_brief — servidor​

campoobrigatório
title✅
summary✅
rules✅

Validável, mas não emitível por ferramenta. O servidor do Criativo o emite só depois de você confirmar a prontidão — nunca por uma chamada de ferramenta do modelo.

Desde o ADR 0185 o clique que o pede — "Estou pronto — a necessidade está validada" — grava também necessity.validated com productBriefId: null: o brief é o próximo product_brief depois daquele readiness.confirmed, e o handoff que o leva ao PO é aceito em nome de quem clicou (RN-657, RN-658).

task_blocked — servidor​

campoobrigatório
taskId✅
agentId✅
reason✅
diagnosis✅

Emitido quando o DevAgent desiste da tarefa: uma suíte que não fecha, teto de iterações, orçamento estourado ou parada sem sinalização. É o registro do desfecho.

qa_verdict e secops_verdict — servidor​

campoobrigatório
veredito✅ — approved, changes_requested ou needs_user_decision (RN-862), nada mais
resumo✅
itens✅
taskId ou prActionId✅ — exatamente um
coverageMatrixopcional, só QA

Três validações a mais moram aqui:

O veredito é fechado nos mesmos valores da máquina de estados de gate da api. Um valor fora disso faria o caso de uso explodir mais adiante — recusar o artefato na emissão é o lugar certo de falhar.

O sujeito é exclusivo. Um veredito é sobre uma tarefa de dev (taskId) ou sobre uma PR de infra (prActionId) — nunca os dois, nunca nenhum. Mesmo tipo de artefato, consumidores diferentes.

coverageMatrix é opcional de propósito. Um veredito de QA sem matriz de cobertura continua sendo um veredito válido; perdê-lo inteiro por um campo ausente seria pior do que gravá-lo incompleto.

O SecOps é determinístico — não tem LLM. O veredito de QA nasce da ferramenta emit_qa_verdict, cobrada à parte. Em nenhum dos dois casos o modelo escolhe emitir.

infra_delegation_files — servidor​

campoobrigatório
files✅ — lista não vazia
summary✅

Resultado de UM delegado da área de Infra (Fase 8c, ADR 0038) — o próprio lead (Dockerfiles/compose) ou o subagente de Workflows (pipeline de CI). O InfraLeadServer o emite depois que cada delegado termina, só para ter um parecer_artifact_id a referenciar na tabela delegations — nunca visto de fora da área. O que a api vê é a PR consolidada, via open_infra_pr (o mesmo mecanismo de sempre, intocado pela Fase 8c).

files vazio reprova pelo mesmo motivo de nada_a_validar/1 no InfraGateRunner (ADR 0021): um delegado sem arquivo nenhum não terminou nada, e "vazio" nunca deve passar por "feito".

prototipo_navegavel — ferramenta (propose_prototype, não emit_artifact)​

campoobrigatório
personas✅ — lista não vazia
jornadas✅ — lista não vazia
prototipo✅ — telas não vazia
resumo✅

O protótipo que o UX Designer produz (ADR 0087), a partir da necessidade-de-negocio do Criativo. Não é note/business_rule — o UX Designer emite via propose_prototype, uma ferramenta DEDICADA (Engine.Agents.UxDesignerTools), e este módulo só valida a FORMA, o mesmo mecanismo do product_brief: validável aqui sem estar na lista de tipos emitíveis via emit_artifact.

personas/jornadas vazias, ou um prototipo sem tela nenhuma, reprovam pela mesma regra de business_rule.origin (a tabela de business_rule acima): artefato sem conteúdo não vale o registro. Um propose_prototype bem-sucedido encerra o turno (o mesmo raciocínio de propose_execution_plan/propose_infra_pr) — sem proposed_action, sem suspensão: propor um protótipo não tem efeito externo.

plano_de_teste — servidor​

campoobrigatório
storyId✅
taskId✅ — desde o ADR 0192
planoDeTeste✅
criteriosExecutaveis✅ — lista não vazia
estrategiaDeAutomacao✅

O entregável do QA-estratégia (ADR 0090; docs/fluxo.yml, papel qa-estrategia, o segundo momento do qa-lead). Desde o ADR 0192 (RN-674) ele é o plano de teste da ENTREGA de UMA tarefa, escrito DEPOIS que o dev agent entregou, sobre o worktree do dev e os arquivos que a entrega tocou: é o primeiro passo do ciclo qa-verificada (QaLeadServer.run_area/3), consumido como ENTRADA pela subespecialidade de Automação, e reencontrado por taskId na rodada de correção. Até o ADR 0192 ele era emitido ANTES do dev e alimentava o gate implementavel. Ele nasce de emit_plano_de_teste, mas o modelo não emite o artefato direto — Engine.Gates.QaEstrategiaAgent extrai o resultado da chamada de ferramenta e chama ArtifactEmitter.emit/5, o mesmo padrão de qa_verdict/task_blocked.

criteriosExecutaveis vazio reprova pelo mesmo motivo de infra_delegation_files: um plano sem critério nenhum não é plano.

threat_model — servidor​

campoobrigatório
storyId✅
threatModel✅
requisitosDeSeguranca✅

O "segundo momento" do SecOps (RN-360, ADR 0090) — um checklist STRIDE-lite sobre o DESENHO de uma história, antes de existir código, o mesmo padrão de segundo momento do qa-estrategia. Engine.Gates.SecOpsAgentServer.run_design/2 emite depois que Engine.Gates.AppSecAgent.run/3 (sem Terminal, sem Diff/Scanner/DevAgentState) termina o laço com emit_threat_model — o modelo não escolhe emitir, o servidor emite quando o laço acaba.

riscos fica fora dos campos obrigatórios: lista vazia é resposta válida (nem toda história carrega risco residual) e a ferramenta já garante que a CHAVE existe — não há "esquecido" a distinguir de "nenhum".

O artefato é sempre gravado, mas os HANDOFFS que o levam não: desde a RN-636 o AppSec o oferece só a um destino (arquiteto, dev-lead, infra) que não tem oferta pendente e não está ativo no projeto. O threat model de uma segunda história fica no log sem oferta própria — a primeira oferta, ainda pendente, não é substituída (ADR 0182).

Artefatos que não passam por aqui​

Alguns tipos de evento artifact.* existem no log sem estar neste registro, porque são emitidos pela api, não pelo engine:

eventoorigem
artifact.module_mapo Arquiteto, via caso de uso na api — cada módulo pode carregar resources (cpus, memoryMb, pidsLimit), e a Infra sobe o container com a SOMA deles (ADR 0199, RN-683)
artifact.insightanálise, via caso de uso na api
artifact.project_imageo Arquiteto, via caso de uso na api (ADR 0065, RN-105)
artifact.module_routingo Arquiteto, via caso de uso na api — uma imagem candidata por módulo do module_map vigente; o Arquiteto CANDIDATA, a Infra ELEGE num passo posterior (ADR 0131, RN-487)
artifact.module_contractso Arquiteto, via caso de uso na api — por módulo do module_map vigente, o que ele EXPÕE; lido pelos dev agents por listar_contratos_de_modulos em vez do worktree de outro módulo (ADR 0200, RN-684)

Eles têm validações próprias no domínio da api. A assimetria é histórica, e está registrada como dívida técnica: o ideal seria todo artifact.* passar por um registro único.

Quando a validação falha​

errocausa
{:unknown_type, tipo}tipo fora dos doze
{:missing_keys, [...]}campos obrigatórios ausentes, todos nomeados
:origem_invalidabusiness_rule.origin vazio ou não é lista
{:sujeito_invalido, chaves}veredito com os dois sujeitos, ou com nenhum
{:veredito_invalido, valor}veredito fora de approved / changes_requested / needs_user_decision
:invalid_payloado payload não é um mapa

A falha volta ao agente como resultado da ferramenta. Um modelo que emite um artefato malformado recebe o erro e pode corrigi-lo — dentro do teto de iterações do ToolLoop.