Source: live external MCP run against ss-prod Sales Dashboard (docs/2026-09-07-sales-prod-mcp-run.md) proved the initial-bootstrap chain externally unreachable: register_draft_pack requires a principal-owned AgentRun but no MCP operation created one after the chat decommission; the vertical E2E masked the gap with a raw-ORM prerequisite seed. T029i: MCP create_agent_run/get_agent_run (mcp_server/tools_agent_run.py) over Services.AgentRuns.Service.Create — REST-parity EXECUTE/READ permissions, human-only, server-pinned UIContext, idempotency-key replay; catalog 2.1.0->2.2.0; MCPX-FR-027 external-reachability invariant pinned; initial-scenario E2E converted to the fully external chain (zero non-MCP seeding); strict-xfail pin flipped as designed, unmarked and hardened (E2E-EXT-001 CLOSED). T029k: ScenarioGraph.CapabilityAuthority — truthful capability facts derived from the authoritative DashboardQueryModel (mutation-context capabilities never derived), derived-wins merge over caller declarations, single choke point wired into MCP inspect_scenario / inspect_dashboard_context and REST api_compile_scenario; CAP-001 classification-fix test on the sales-shape fixture (B02-B04/T01-T03 automated, C04-C06 unsupported, unsafe-mutation cases legitimately human). T029l: disposition vocabulary clarity — RU/EN labels name the persisted outcome (confirm->passed), confirm restyled bg-destructive->bg-primary, decide_checkpoint description carries the immutable outcome table; lifecycle mapping and API vocabulary unchanged (DISP-001 CLOSED). Decision memory: ADR-0024 (IMPLEMENTED, 4 rejected alternatives incl. no-AgentRun boundary and implicit auto-create) + README registry; 050 MCPX-FR-027/028/029 + release-gate rows + Clarifications session 2026-09-07; 038/044/045 field-run amendments -> IMPLEMENTED; WORKSTATE checkpoints (plan round + execution round). Pre-existing HEAD regressions surfaced by the first full-suite rerun since 4d5ef6be/58c5ae39 and fixed: (1) stale SC-007 resource pin — canonical identifier is the post-redirect /mcp/ (code + twin pin aligned since the batches; test_mcp_client_flow_http pin updated with rationale); (2) app-lifespan tests re-entered the run-once StreamableHTTPSessionManager module singleton — autouse fresh-transport-app fixture (production lifespan runs once per process; singleton stays correct there). Gates: full backend suite 11357 passed / 243 skipped / 1 xpassed / 0 failed (first green full run since the batches); MCP+catalog slice 70 passed; capability slice 67 passed; frontend vitest 3507 passed (206 files), lint 0 errors (364 baseline warnings), build OK; ruff/compileall clean; anchors balanced; scoped git diff --check clean. INV_7 watch: tools_scenario.py 508 LOC and routes scenario.py 442 LOC flagged for the next decomposition pass (new code lives in new modules 155/236 LOC). OPEN: T029m / E2E-EXT-002 — live-stand replay of the sales scenario through the full external chain. Not included (foreign uncommitted workstream): translate/migration integration tests, _job_routes.py, .kilo/agent-manager.json, specs-036-050-20260907-111314.md.
Реестр архитектурных решений
ADR фиксирует принятое и проверяемое архитектурное решение. Это не план работ и
не каталог желаемой архитектуры: обещание, которое ещё не реализовано, должно
иметь статус PROPOSED или быть вынесено в spec.
Статусы
| Статус | Значение |
|---|---|
ACCEPTED |
Решение действует и соответствует реализации. |
PARTIALLY IMPLEMENTED |
Направление принято, но в репозитории есть существенная незавершённая часть. |
SUPERSEDED |
Решение заменено указанным ADR; исторический файл не меняет действующую архитектуру. |
REJECTED |
Альтернатива запрещена; это не описание действующей реализации. |
PROPOSED |
Решение обсуждается и не должно считаться обязательным. |
Актуальный реестр
| ADR | Статус | Проверенное содержание |
|---|---|---|
| 0001 | PARTIALLY IMPLEMENTED |
Базовое разделение backend/frontend/docs/specs сохранено; точная схема файла устарела. |
| 0002 | ACCEPTED |
Семантические skills и контракты в исходном коде остаются правилом репозитория. |
| 0003 | ACCEPTED |
Сервис остаётся внешним оркестратором Superset. |
| 0004 | SUPERSEDED |
Заменён ADR-0016: исходный subprocess/TOML-контракт не был реализован. |
| 0005 | ACCEPTED |
Локальная аутентификация, RBAC и ADFS JIT provisioning реализованы. |
| 0006 | ACCEPTED |
Svelte 5, Screen Models и UI atoms применяются в frontend. |
| 0007 | REJECTED |
Комбинация fromStore с несколькими $derived запрещена. |
| 0008 | ACCEPTED |
Декораторный registry реализован в backend/src/api/routes/assistant/_tool_registry.py. |
| 0009 | ACCEPTED |
Управление корпоративными CA реализовано в Docker и HTTP-клиентах. |
| 0010 | ACCEPTED |
Порог декомпозиции Screen Model остаётся архитектурным ограничением. |
| 0011 | PARTIALLY IMPLEMENTED |
Async Task Manager, EventBus и bounded executors внедрены; утверждение о полном отказе от sync-кода не подтверждено. |
| 0012 | ACCEPTED |
Интеграционные Superset-тесты используют Postgres, init/web контейнеры и superset_config.py. |
| 0013 | ACCEPTED |
scripts/coverage-summary.sh существует и собирает сводный отчёт. |
| 0014 | SUPERSEDED |
Заменён ADR-0015. |
| 0015 | SUPERSEDED |
Заменён ADR-0022: agent-контейнер удалён, второй runtime исчез. |
| 0016 | ACCEPTED |
Плагины загружаются в процессе из backend/src/plugins через PluginBase. |
| 0017 | ACCEPTED |
Agent-centric traces achieved by editing call sites (meaningful intents, removal of per-request noise) rather than only adding complexity to the logger. |
| 0018 | REJECTED |
Dataset Review is removed from the active product; specs/027-dataset-llm-orchestration/ is retained only as archived history. |
| 0019 | ACCEPTED |
UUID-трансформация БД (не strip_databases), cross-filter patching через IdMappingService, password injection flow (await_input→wait_for_input→retry), разделение dry-run/execute, парсинг имён YAML-файлов БД. |
| 0020 | ACCEPTED |
Обнаружение виртуальных (SQL) датасетов в maintenance discovery через серверный фильтр sql is_not_null (fallback — клиентский скан по непустому sql); AsyncAPIClient.request поднимает не-2xx ответы (raise_for_status); sqlparse token-limit (10000) fallback к regex-only для гигантских виртуальных датасетов. |
| 0021 | ACCEPTED |
Самодиагностируемый EXPLORE: опциональные contract_id/claim/error_code/loc в wire-формате; токен-экономика (payload-cap 2KB, heartbeat-правило, bond-метрики единым движком src/core/log_stats.py); ground-truth триангуляция task-log-gaps (T1/T2/T3); детекция тихих отказов — только в axiom-mcp (BELIEF_SILENT_*), без pytest-гейта. |
| 0022 | ACCEPTED |
Пакет shared/ поглощён backend'ом после удаления агента: cot_logger → src/core/, CotJsonFormatter → src/core/cot_formatter.py, _llm_*/ssl → src/core/utils/; единый фасад src/core/logger.py; run.sh/Dockerfile без pip install -e ../shared. |
| 0023 | IMPLEMENTED |
MCP-стадии inspect/compile/validate/resolve/draft-pack изначально не создавали серверные *Handle, а create_scenario/create_initial писали в graph_snapshot только provenance-метаданные (риск вакуумного false PASS, закрыт guard'ом BOOTSTRAP_REVISION_NOT_RUNNABLE). Реализован полный handle-слой: CompiledScenarioHandle/ValidationResultHandle/DraftPackHandle (migrations 0019–0021), canonical-bytes authority, single consumption под FOR UPDATE (PostgreSQL-proven), материализация графа в create-транзакции, outbox-worker в scheduler poll loop, MCP register_draft_pack + handle-only bootstrap, гибрид T029h (inspect_dashboard_context + context_authority binding + PROD gate). Guard демотирован до defense-in-depth. |
| 0024 | IMPLEMENTED |
Полевой MCP-прогон 2026-09-07 (ss-prod Sales Dashboard) доказал: register_draft_pack требует principal-owned AgentRun, но после демонтажа чата (050 T041) ни одна MCP-операция его не создаёт — external initial-bootstrap цепочка недостижима, хотя все звенья реализованы. Вертикальный E2E маскировал разрыв raw-ORM-seed'ом предусловия. Реализовано в тот же день: MCP create_agent_run/get_agent_run (tools_agent_run.py, каталог 2.2.0, EXECUTE/READ human-only), инвариант внешней достижимости MCPX-FR-027 с hard-green пином (test_mcp_agent_run_reachability.py), test-honesty remediation (E2E-вертикаль конвертирована в fully external chain, zero non-MCP seeding), companion-gaps T029k (derived capabilities, CAP-001) и T029l (disposition clarity, DISP-001). Полные гейты: backend 11357 passed / frontend 3507 passed. Open: live-stand replay E2E-EXT-002 (T029m). |
Правила сопровождения
- Новый ADR добавляется только для решения, которое меняет границу модулей, runtime/topology, безопасность, данные или постоянный способ разработки.
- Каждый ADR содержит контекст, решение, последствия и отклонённые альтернативы.
- При изменении решения создаётся новый ADR со ссылкой на заменённый, а прежний
получает
SUPERSEDED; историю не переписывают. - В ADR указываются существующие пути и проверяемые факты. Версии, пороги и команды обновляются вместе с кодом либо заменяются ссылкой на источник истины.