Files
ss-tools/docs/adr
busya 9c1a1e093c feat(mcp): Phase 2d field-run remediation — ADR-0024 agent-run surface, derived capabilities, disposition clarity
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.
2026-09-07 16:52:38 +03:00
..

Реестр архитектурных решений

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).

Правила сопровождения

  1. Новый ADR добавляется только для решения, которое меняет границу модулей, runtime/topology, безопасность, данные или постоянный способ разработки.
  2. Каждый ADR содержит контекст, решение, последствия и отклонённые альтернативы.
  3. При изменении решения создаётся новый ADR со ссылкой на заменённый, а прежний получает SUPERSEDED; историю не переписывают.
  4. В ADR указываются существующие пути и проверяемые факты. Версии, пороги и команды обновляются вместе с кодом либо заменяются ссылкой на источник истины.