Files
ss-tools/docs/adr/README.md
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

55 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Реестр архитектурных решений
ADR фиксирует принятое и проверяемое архитектурное решение. Это не план работ и
не каталог желаемой архитектуры: обещание, которое ещё не реализовано, должно
иметь статус `PROPOSED` или быть вынесено в spec.
## Статусы
| Статус | Значение |
|---|---|
| `ACCEPTED` | Решение действует и соответствует реализации. |
| `PARTIALLY IMPLEMENTED` | Направление принято, но в репозитории есть существенная незавершённая часть. |
| `SUPERSEDED` | Решение заменено указанным ADR; исторический файл не меняет действующую архитектуру. |
| `REJECTED` | Альтернатива запрещена; это не описание действующей реализации. |
| `PROPOSED` | Решение обсуждается и не должно считаться обязательным. |
## Актуальный реестр
| ADR | Статус | Проверенное содержание |
|---|---|---|
| [0001](ADR-0001-module-layout.md) | `PARTIALLY IMPLEMENTED` | Базовое разделение backend/frontend/docs/specs сохранено; точная схема файла устарела. |
| [0002](ADR-0002-semantic-protocol.md) | `ACCEPTED` | Семантические skills и контракты в исходном коде остаются правилом репозитория. |
| [0003](ADR-0003-orchestrator-pattern.md) | `ACCEPTED` | Сервис остаётся внешним оркестратором Superset. |
| [0004](ADR-0004-plugin-architecture.md) | `SUPERSEDED` | Заменён ADR-0016: исходный subprocess/TOML-контракт не был реализован. |
| [0005](ADR-0005-auth-rbac.md) | `ACCEPTED` | Локальная аутентификация, RBAC и ADFS JIT provisioning реализованы. |
| [0006](ADR-0006-frontend-architecture.md) | `ACCEPTED` | Svelte 5, Screen Models и UI atoms применяются в frontend. |
| [0007](ADR-0007-rejected-fromStore-derived.md) | `REJECTED` | Комбинация `fromStore` с несколькими `$derived` запрещена. |
| [0008](ADR-0008-assistant-tool-registry.md) | `ACCEPTED` | Декораторный registry реализован в `backend/src/api/routes/assistant/_tool_registry.py`. |
| [0009](ADR-0009-ssl-certificate-management.md) | `ACCEPTED` | Управление корпоративными CA реализовано в Docker и HTTP-клиентах. |
| [0010](ADR-0010-model-decomposition-gate.md) | `ACCEPTED` | Порог декомпозиции Screen Model остаётся архитектурным ограничением. |
| [0011](ADR-0011-async-backend.md) | `PARTIALLY IMPLEMENTED` | Async Task Manager, EventBus и bounded executors внедрены; утверждение о полном отказе от sync-кода не подтверждено. |
| [0012](ADR-0012-superset-testcontainers.md) | `ACCEPTED` | Интеграционные Superset-тесты используют Postgres, init/web контейнеры и `superset_config.py`. |
| [0013](ADR-0013-coverage-reporting.md) | `ACCEPTED` | `scripts/coverage-summary.sh` существует и собирает сводный отчёт. |
| [0014](ADR-0014-agent-source-copy-strategy.md) | `SUPERSEDED` | Заменён [ADR-0015](ADR-0015-agent-shared-package-boundaries.md). |
| [0015](ADR-0015-agent-shared-package-boundaries.md) | `SUPERSEDED` | Заменён ADR-0022: agent-контейнер удалён, второй runtime исчез. |
| [0016](ADR-0016-in-process-plugin-runtime.md) | `ACCEPTED` | Плагины загружаются в процессе из `backend/src/plugins` через `PluginBase`. |
| [0017](ADR-0017-agent-centric-logging.md) | `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](ADR-0018-rejected-dataset-review.md) | `REJECTED` | Dataset Review is removed from the active product; `specs/027-dataset-llm-orchestration/` is retained only as archived history. |
| [0019](ADR-0019-dashboard-import-mechanism.md) | `ACCEPTED` | UUID-трансформация БД (не strip_databases), cross-filter patching через IdMappingService, password injection flow (await_input→wait_for_input→retry), разделение dry-run/execute, парсинг имён YAML-файлов БД. |
| [0020](ADR-0020-maintenance-virtual-dataset-discovery.md) | `ACCEPTED` | Обнаружение виртуальных (SQL) датасетов в maintenance discovery через серверный фильтр `sql is_not_null` (fallback — клиентский скан по непустому `sql`); `AsyncAPIClient.request` поднимает не-2xx ответы (`raise_for_status`); sqlparse token-limit (10000) fallback к regex-only для гигантских виртуальных датасетов. |
| [0021](ADR-0021-self-diagnosing-explore.md) | `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](ADR-0022-absorb-shared-into-backend.md) | `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](ADR-0023-mcp-scenario-pipeline-handle-gap.md) | `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](ADR-0024-mcp-agent-run-external-boundary.md) | `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 указываются существующие пути и проверяемые факты. Версии, пороги и
команды обновляются вместе с кодом либо заменяются ссылкой на источник истины.