ADR 0196 — Anamnese снова включена: не работает без субъекта, а принятая гипотеза становится фактом профиля
Статус
Accepted. 2026-10-01 (AT-277, история HS-072, эпик EP-030, раунд 36;
решение владельца от 01.10: "religar a Anamnese com correções" — защита
допустимого субъекта, а ПРИНЯТАЯ гипотеза становится фактом профиля в графе и входит в
контекст агентов, разговаривающих с человеком; отклонённая лишь
регистрируется). Завершает паузу от 2026-08-10 только для Anamnese — Psicólogo
остаётся на паузе (PSYCHOLOGIST_ENABLED=false). Использует граф
ADR 0099 так, как он был задуман
(ПРОИЗВОДНАЯ память event log), и путь эфемерной ориентации языка
(RN-622), не редактируя ни то, ни другое.
Контекст
Измерено в коде dev и в отчёте о реальном использовании от 2026-09-29, до
изменения:
- Шесть раундов, шесть
anamnese.run_skipped, написанных МОДЕЛЬЮ с одной и той же причиной, "nenhum membro elegível" (сессииbe70,67f3,d7e9×2,5d66×2), на 8 933 micros за 6 вызовов.anamnese_runs= 0,proficiency_profiles= 0. - Откуда брался субъект:
GetAnamneseContextUseCaseчиталProjectRepository.listMembers, то есть ТОЛЬКОproject_members. Создание проекта не записывает туда строку (CreateProjectUseCase), а авторизация считает владельца workspace участником проекта черезprojectRole ?? workspaceRole(RN-471). В проекте одного человека список был пуст всегда. - Worker не смотрел на список:
AnamneseWorker.maybe_analyze/3лишь спрашивал триаж (объём окна, очередь гипотез), а гипотеза в очереди ПРИНУЖДАЛА раунд. Prompt говорил "(nenhum membro elegível)", и модели платили за то, чтобы прийти к этому выводу. - У принятой гипотезы не было реального потребителя:
AcceptHypothesisUseCaseставил в очередьanamnese_queue(3 строки в реальном использовании), а единственным потреблением былpropose_instruction_patchодного раунда — который в5d66seq 17 ответил "não há arquivo de instrução de agente disponível no contexto". Граф не проецировалpsychologist.hypothesis_accepted. - У пути чтения графа не было потребителя:
QueryUserContextUseCaseсуществовал (гипотезы, профили, handoffs по пользователю и проекту), и никакой код его не вызывал. ANAMNESE_ENABLEDимел defaultfalseвruntime.exsи в трёх compose с RN-540; отчёт фиксирует engine реального использования с флагомtrueчерез окружение.
Решение
- Раунд не выполняется без допустимого субъекта.
Engine.Anamnese.Elegibilidadeрешает ДО триажа, без исключений (даже очередь гипотез его не обходит): субъект — ДЕЙСТВУЮЩИЙ участник проекта, вне opt-out, с СОБСТВЕННЫМ взаимодействием в том, что показывает prompt, — его событиеactor_kind: "user"в окне или его решение. Без субъекта: ни одного вызова LLM, ни одного поиска в RAG, названная причина в журнале engine (sem_sujeito_elegivel, сnenhum_membroилиnenhuma_interacao_propriaи числами) и только в раунде, запрошенном вручную (origem: "manual"), — durableanamnese.run_skipped. Prompt начинает перечислять только субъектов. - Участник проекта — это ДЕЙСТВУЮЩИЙ участник.
ProjectRepositoryполучаетlistEffectiveMembers(membrosEfetivos, мерило RN-471: строка проекта перекрывает строку workspace в обе стороны), используемый тремя use cases Anamnese.listMembersостаётся толькоproject_members— тем, что редактирует экран Участников. - Принятая гипотеза становится ФАКТОМ профиля, производным от event log.
psychologist.hypothesis_acceptedначинает нестиprojectId,sujeito(автор анализируемой сессии),hipotese,sugestaoиfatoDoPerfil.GraphEventTranslator— ТОТ ЖЕ, что у проектора иgrafo:reprojetar, — переводит его в(:FatoDoPerfil {hypothesisId})-[:SOBRE]->(:Usuario)и-[:NO_PROJETO]->(:Projeto)(RecordProfileFactUseCase,MERGEпо гипотезе, новое ограничение уникальности). Событие самодостаточно: перепроецирование не читаетpsychologist_hypotheses. - Факт рождается только из клика самого субъекта.
fatoDoPerfilравноtrue, когда принявший ЯВЛЯЕТСЯ автором сессии. Принятие третьим лицом продолжает действовать для всего прочего (статус, очередь Anamnese) и говорит в payload, почему оно не стало фактом (motivoSemFato). Отклонённая не меняется: лишь регистрируется. - Факт входит в контекст агентов, разговаривающих с человеком.
SendAgentMessageUseCaseчитает факты АВТОРА сообщения черезQueryUserContextUseCase— в пределах проекта, 5 самых свежих, с общим числом рядом — и отправляет их в engine какperfilDoAutor, текст, собранныйtextoDoPerfilDoAutor(не более 2 000 символов, срез объявлен). Engine помещает их в ход ТЕМ ЖЕ путём, что и язык: controller объединяет оба в одну карту,IdiomaDaResposta.com_idioma_do_autor/2её распознаёт, а фасадEngineApiClientдобавляет текст как ЭФЕМЕРНОЕ сообщениеsystemперед ориентацией языка (Engine.Harness.PerfilDoAutor). Ни один сервер агента не меняется. Недоступный граф становится записью в журнале, и ход идёт без фактов. - Включить снова. Default
ANAMNESE_ENABLEDвозвращается кtrueвruntime.exsи в трёх compose (мерилоflags-do-engine-no-compose.spec.tsсохраняется: compose повторяет код).START_ANAMNESEне меняется нигде:trueв коде, в dev и в установке;falseв продакшен-compose, расхождение уже объявлено.PSYCHOLOGIST_ENABLEDне меняется.
Последствия
- Реальное использование от 29.09 перестаёт тратить: проект без субъекта не доходит до LLM. А владелец workspace в проекте без собственной строки начинает БЫТЬ субъектом — снова включённая Anamnese начинает что-то делать в самом частом случае, вместо ничего.
- Объявленная цена: Anamnese теперь профилирует того, кто является участником лишь через workspace. Участник workspace, никогда не взаимодействовавший в проекте, не профилируется (он не субъект), и opt-out продолжает действовать.
- Объявленная цена: каждое сообщение разговорному агенту делает одно
дополнительное чтение графа (четыре запроса
QueryUserContextUseCase). Без настроенного Neo4j это немедленныйGraphUnavailableErrorи запись в журнале. - Объявленная цена: факты доходят до КАЖДОГО хода автора, в том числе до агента, который не был адресатом гипотезы, — метка говорит, к кому она была обращена, а фильтрация по агенту — открытое решение.
- Вне, объявлено: три принятия реального использования были записаны до этого изменения, без полей факта, и НЕ становятся фактом при перепроецировании. Они остаются в очереди Anamnese, которая читает их в следующем раунде С субъектом. Ход без автора (kickoff, dev agents, gates) не получает фактов. Staff остаётся без автоматического триггера: Anamnese никогда не запускала его в коде.
- Раунд по тику без субъекта не становится событием (это было бы предупреждение каждые 15 минут на проект); повествует только запрошенный вручную.