Перейти к основному содержимому

Артефакты

Артефакт — это структурированный и проверенный результат работы агента. Конкретно: событие artifact.<тип> в журнале, payload которого проверяется по закрытой схеме до записи.

Таблицы артефактов не существует. Проверка выполняется в одном месте — Engine.Harness.ArtifactSchemas, — и отсутствие обязательного поля отклоняет выпуск, вместо того чтобы записать артефакт наполовину.

Кто что может выпускать​

Это самое важное различие на странице, и его легко не заметить:

источникзначение
инструментмодель решает выпустить артефакт, вызывая emit_artifact
серверкод выпускает артефакт, когда наступает исход; модель не выбирает

Через инструмент можно выпустить только три типа: note, business_rule и decision_record. Всё остальное выпускает сервер.

Причина во всех случаях одна: когда артефакт — это запись исхода, позволить модели выбирать, выпускать ли его, значит позволить ей его опустить. DevAgent, который сдаётся, не должен иметь возможности решить не записывать, что он сдался.

Тип сессии не фильтрует ни один артефакт. RN-097 дала сессии kind (consultiva | criativa) и поставила проверку на добавление событий, но она касается одного типа — execution.activated, — и ни один артефакт им не является. Консультативная сессия записывает artifact.business_rule точно так же: она лишь не переходит к исполнению. Тот, кто приходит к правилу типа, склонен предполагать обратное, и ошибочное предположение здесь стёрло бы запись целого разговора.

СОСТОЯНИЕ сессии фильтрует по актору. Начиная с RN-581 сессия closed/closed_abnormally отклоняет разговор с 409, а «разговор» включает любое событие, актором которого является разговорный агент, — поэтому artifact.* от Криативо, PO, Архитектора, Dev Lead, UX Designer, Staff или Infra Lead больше не попадает в закрытую сессию, тогда как те же типы артефактов, выпущенные Психологом, который работает поверх закрытой сессии, попадают. Решает никогда не тип, а актор.

Схемы​

note — инструмент​

полеобязательное
title✅
body✅

business_rule — инструмент​

полеобязательное
title✅
description✅
origin✅ — непустой список

origin ссылается на события разговора, из которых возникло правило. Пустой список отклоняется: это прослеживаемость правила до места, где оно было сформулировано, и без неё правило становится утверждением без происхождения.

:::caution Модель должна ЗНАТЬ имена полей Описание инструмента emit_artifact генерируется из этих схем (ArtifactSchemas.required/1) и называет каждое обязательное поле, на английском, с заполненным примером.

Это не педантизм: прежнее описание говорило лишь «выпускает типизированный артефакт» и перечисляло типы. В реальном запуске модель — ведя разговор на португальском — угадала titulo/descricao/comportamento, и все четыре бизнес-правила того разговора были молча отклонены. origin в виде свободного текста тоже отклоняется: это должен быть список, и описание говорит об этом прямо (RN-061). :::

decision_record — инструмент​

полеобязательное
context✅
options✅ — список
choice✅
consequences✅

«Краткий ADR», который может выпустить любой из шести разговорных агентов — Криативо, PO, Архитектор, Dev Lead, UX Designer и Staff имеют emit_artifact с этим типом (RN-505). Намеренно без проверки между полями: choice не обязан буквально совпадать с одним из options — свободный текст надёжнее, а общая схема проверяет только наличие ключей, та же мерка, что у note/business_rule.

Он повторно использует общий шаблон вместо специального (artifact.project_image/artifact.c4_diagram, версионируемый, собственная TS-схема, собственный HTTP-маршрут): решение по природе append-only, а не «действующее» значение, которое заменяется. Он намеренно отличается от open_adr_pr (только у Архитектора, коммитит настоящий файл в docs/adr/*.md и открывает настоящий PR с обязательным одобрением человека) — оба сосуществуют для разных масштабов решений: decision_record без трения, доступен для поиска в журнале сессии, для любого значимого решения; open_adr_pr — для случая, когда решение достаточно велико, чтобы стать настоящим документом репозитория.

open_question — собственный инструмент​

полеобязательное
questionId✅ — uuid, генерируется инструментом
pergunta✅ — до 500 символов
afeta✅ — {regras, historias, tarefas}, списки id
sugestaoнеобязательное — до 300 символов

Вопрос, который агент оставляет пользователю (ADR 0214, RN-862). Его нельзя выпустить через emit_artifact: его выпускают только Криативо, PO, Архитектор и Dev Lead, собственным инструментом declare_open_question, который записывает также autor и sessionId. api закрывает его событием open_question.answered.

product_brief — сервер​

полеобязательное
title✅
summary✅
rules✅

Проверяемый, но не выпускаемый через инструмент. Сервер Криативо выпускает его только после того, как вы подтвердите готовность, — никогда по вызову инструмента моделью.

Начиная с ADR 0185 нажатие, которое его запрашивает, — «Я готов — потребность подтверждена», — записывает также necessity.validated с productBriefId: null: brief — это следующий product_brief после того readiness.confirmed, а handoff, передающий его PO, принимается от имени нажавшего (RN-657, RN-658).

task_blocked — сервер​

полеобязательное
taskId✅
agentId✅
reason✅
diagnosis✅

Выпускается, когда DevAgent отказывается от задачи: набор тестов, который не сходится, предел итераций, превышенный бюджет или остановка без сигнала. Это запись исхода.

qa_verdict и secops_verdict — сервер​

полеобязательное
veredito✅ — approved, changes_requested или needs_user_decision (RN-862), ничего больше
resumo✅
itens✅
taskId или prActionId✅ — ровно одно
coverageMatrixнеобязательное, только QA

Здесь живут ещё три проверки:

Вердикт закрыт теми же значениями, что и машина состояний гейта в api. Значение вне этого набора заставило бы use case упасть дальше — отклонить артефакт при выпуске и есть правильное место для отказа.

Субъект исключителен. Вердикт относится к одной задаче dev (taskId) или к одному PR инфраструктуры (prActionId) — никогда к обоим, никогда ни к одному. Тот же тип артефакта, разные потребители.

coverageMatrix необязательно намеренно. Вердикт QA без матрицы покрытия остаётся допустимым вердиктом; потерять его целиком из-за отсутствующего поля было бы хуже, чем записать его неполным.

SecOps детерминирован — у него нет LLM. Вердикт QA рождается из инструмента emit_qa_verdict, тарифицируемого отдельно. Ни в одном из случаев модель не выбирает, выпускать ли.

infra_delegation_files — сервер​

полеобязательное
files✅ — непустой список
summary✅

Результат ОДНОГО делегата области Infra (Фаза 8c, ADR 0038) — самого лида (Dockerfile/compose) или субагента Workflows (CI-пайплайн). InfraLeadServer выпускает его после завершения каждого делегата, только чтобы иметь parecer_artifact_id для ссылки в таблице delegations, — он никогда не виден вне области. То, что видит api, — это сводный PR через open_infra_pr (тот же механизм, что и всегда, не затронутый Фазой 8c).

Пустой files отклоняется по той же причине, что и nada_a_validar/1 в InfraGateRunner (ADR 0021): делегат без единого файла ничего не завершил, и «пусто» никогда не должно сходить за «сделано».

prototipo_navegavel — инструмент (propose_prototype, не emit_artifact)​

полеобязательное
personas✅ — непустой список
jornadas✅ — непустой список
prototipo✅ — непустой telas
resumo✅

Прототип, который создаёт UX Designer (ADR 0087), на основе necessidade-de-negocio Криативо. Это не note/business_rule — UX Designer выпускает его через propose_prototype, ВЫДЕЛЕННЫЙ инструмент (Engine.Agents.UxDesignerTools), а этот модуль проверяет лишь ФОРМУ, тот же механизм, что у product_brief: проверяемый здесь, не входя в список типов, выпускаемых через emit_artifact.

Пустые personas/jornadas или prototipo без единого экрана отклоняются по тому же правилу, что и business_rule.origin (см. таблицу business_rule выше): артефакт без содержания не стоит записи. Успешный propose_prototype завершает ход (то же рассуждение, что у propose_execution_plan/propose_infra_pr) — без proposed_action, без приостановки: предложение прототипа не имеет внешнего эффекта.

plano_de_teste — сервер​

полеобязательное
storyId✅
taskId✅ — начиная с ADR 0192
planoDeTeste✅
criteriosExecutaveis✅ — непустой список
estrategiaDeAutomacao✅

Результат QA-стратегии (ADR 0090; docs/fluxo.yml, роль qa-estrategia, второй момент qa-lead). Начиная с ADR 0192 (RN-674) это план тестирования ПОСТАВКИ ОДНОЙ задачи, написанный ПОСЛЕ того, как dev agent сдал работу, по worktree dev и файлам, которые затронула поставка: это первый шаг цикла qa-verificada (QaLeadServer.run_area/3), потребляемый как ВХОД подспециальностью Автоматизации и находимый снова по taskId в раунде исправлений. До ADR 0192 он выпускался ДО dev и питал гейт implementavel. Он рождается из emit_plano_de_teste, но модель не выпускает артефакт напрямую — Engine.Gates.QaEstrategiaAgent извлекает результат вызова инструмента и вызывает ArtifactEmitter.emit/5, тот же шаблон, что у qa_verdict/task_blocked.

Пустой criteriosExecutaveis отклоняется по той же причине, что и infra_delegation_files: план без единого критерия — не план.

threat_model — сервер​

полеобязательное
storyId✅
threatModel✅
requisitosDeSeguranca✅

«Второй момент» SecOps (RN-360, ADR 0090) — чек-лист STRIDE-lite по ДИЗАЙНУ истории, до появления кода, тот же шаблон второго момента, что у qa-estrategia. Engine.Gates.SecOpsAgentServer.run_design/2 выпускает его после того, как Engine.Gates.AppSecAgent.run/3 (без Terminal, без Diff/Scanner/DevAgentState) завершает цикл вызовом emit_threat_model, — модель не выбирает выпуск, сервер выпускает, когда цикл заканчивается.

riscos не входит в обязательные поля: пустой список — допустимый ответ (не каждая история несёт остаточный риск), а инструмент уже гарантирует, что КЛЮЧ существует, — нет «забытого», которое нужно было бы отличать от «никакого».

Артефакт записывается всегда, но HANDOFF, которые его передают, — нет: начиная с RN-636 AppSec предлагает его только тому адресату (arquiteto, dev-lead, infra), у которого нет ожидающего предложения и который не активен в проекте. Threat model второй истории остаётся в журнале без собственного предложения — первое предложение, ещё ожидающее, не заменяется (ADR 0182).

Артефакты, которые проходят не здесь​

Некоторые типы событий artifact.* существуют в журнале, не входя в этот реестр, потому что их выпускает api, а не engine:

событиеисточник
artifact.module_mapАрхитектор, через use case в api — каждый модуль может нести resources (cpus, memoryMb, pidsLimit), и Infra поднимает контейнер с их СУММОЙ (ADR 0199, RN-683)
artifact.insightанализ, через use case в api
artifact.project_imageАрхитектор, через use case в api (ADR 0065, RN-105)
artifact.module_routingАрхитектор, через use case в api — один образ-кандидат на модуль действующего module_map; Архитектор ПРЕДЛАГАЕТ кандидатов, Infra ВЫБИРАЕТ на последующем шаге (ADR 0131, RN-487)
artifact.module_contractsАрхитектор, через use case в api — для каждого модуля действующего module_map то, что он ПРЕДОСТАВЛЯЕТ; читается dev agents через listar_contratos_de_modulos вместо worktree другого модуля (ADR 0200, RN-684)

У них собственные проверки в домене api. Асимметрия историческая и зарегистрирована как технический долг: в идеале каждый artifact.* проходил бы через единый реестр.

Когда проверка не проходит​

ошибкапричина
{:unknown_type, tipo}тип вне двенадцати
{:missing_keys, [...]}отсутствуют обязательные поля, все названы
:origem_invalidabusiness_rule.origin пуст или не является списком
{:sujeito_invalido, chaves}вердикт с обоими субъектами или ни с одним
{:veredito_invalido, valor}вердикт вне approved / changes_requested / needs_user_decision
:invalid_payloadpayload не является отображением (map)

Отказ возвращается агенту как результат инструмента. Модель, выпустившая некорректный артефакт, получает ошибку и может исправить его — в пределах лимита итераций ToolLoop.