Add architecture package and application skeleton
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# ADR 001: Runtime Stack
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
AI Orchestrator должен быть:
|
||||
|
||||
- независимым от Local LLM Platform;
|
||||
- пригодным для долгоживущих task runtime;
|
||||
- удобным для строгой типизации контрактов;
|
||||
- удобным для async I/O: models, MCP, worker connections, event streams;
|
||||
- запускаемым без Docker на локальной машине;
|
||||
- переносимым на удаленное окружение, включая `docker-test`.
|
||||
|
||||
## Decision
|
||||
|
||||
Основной стек:
|
||||
|
||||
- язык: Python 3.13+;
|
||||
- HTTP API: FastAPI;
|
||||
- конфиги и схемы запроса/ответа: Pydantic v2;
|
||||
- app settings: `pydantic-settings`;
|
||||
- конфиги проекта: YAML;
|
||||
- event streaming для UI: SSE как основной transport;
|
||||
- worker transport: WebSocket;
|
||||
- structured logging: JSON lines через стандартный logging layer и event envelopes;
|
||||
- тесты: `pytest` + `pytest-asyncio`;
|
||||
- runtime packaging: стандартный `pyproject.toml`.
|
||||
|
||||
## Why This Stack
|
||||
|
||||
Python хорошо подходит для orchestration-heavy систем, где важнее:
|
||||
|
||||
- строгое моделирование состояния;
|
||||
- быстрая интеграция с внешними AI/MCP endpoint;
|
||||
- асинхронный I/O;
|
||||
- прозрачные схемы данных;
|
||||
- простая локальная разработка без контейнеров.
|
||||
|
||||
FastAPI выбран как delivery adapter, а не как центр архитектуры.
|
||||
Доменные модели и application services не должны зависеть от FastAPI.
|
||||
|
||||
## Consequences
|
||||
|
||||
Плюсы:
|
||||
|
||||
- быстрый путь к строгим контрактам;
|
||||
- хорошая ergonomics для async adapters;
|
||||
- удобный локальный запуск без Docker;
|
||||
- понятный переход к PostgreSQL и production deployment.
|
||||
|
||||
Минусы:
|
||||
|
||||
- нужен дисциплинированный layering, чтобы не “утонуть” в framework-driven code;
|
||||
- CPU-heavy задачи должны оставаться вне основного request loop.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- локальный Docker как обязательный dev path;
|
||||
- тяжелая зависимость от конкретной ORM на уровне domain;
|
||||
- framework-first архитектура.
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# ADR 002: Storage And Persistence Model
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Проект не должен начинаться с чисто временного `in-memory` мышления, иначе потом придется переделывать:
|
||||
|
||||
- task lifecycle;
|
||||
- event log;
|
||||
- confirmations;
|
||||
- worker session tracking;
|
||||
- replay и audit.
|
||||
|
||||
## Decision
|
||||
|
||||
Хранилище проектируется как persistent-first:
|
||||
|
||||
- production target: PostgreSQL;
|
||||
- local development fallback: SQLite без Docker;
|
||||
- repository interfaces определяются в application/domain boundary;
|
||||
- materialized current state хранится отдельно от append-only event log;
|
||||
- критические переходы состояний должны логироваться как события.
|
||||
|
||||
## Data Model Principles
|
||||
|
||||
1. `tasks`, `task_nodes`, `confirmations`, `worker_sessions` хранят текущее состояние.
|
||||
2. `task_events` хранит audit trail и feed для replay/debugging.
|
||||
3. Вызовы моделей, MCP и worker сохраняются как отдельные invocation records.
|
||||
4. Артефакты хранят metadata в БД, а payload может лежать во внешнем файловом хранилище.
|
||||
|
||||
## Consequences
|
||||
|
||||
Плюсы:
|
||||
|
||||
- можно строить UI progress и audit без догадок;
|
||||
- проще реализовать replay/resume;
|
||||
- нет боли миграции с “простых dict” на реальную БД.
|
||||
|
||||
Минусы:
|
||||
|
||||
- немного более сложный старт;
|
||||
- нужно заранее аккуратно продумать схему.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# ADR 003: User Event Stream Transport
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
UI требует поток событий по task execution:
|
||||
|
||||
- `task_started`
|
||||
- `node_started`
|
||||
- `node_completed`
|
||||
- `confirmation_required`
|
||||
- `task_completed`
|
||||
- `task_failed`
|
||||
|
||||
В исходных документах упомянуты `SSE/WebSocket`, но как основной transport нужно выбрать один.
|
||||
|
||||
## Decision
|
||||
|
||||
Основной transport для пользовательского event stream: Server-Sent Events.
|
||||
|
||||
WebSocket не исключается, но считается вторичным adapter для будущих realtime-потребностей.
|
||||
|
||||
## Rationale
|
||||
|
||||
SSE проще для:
|
||||
|
||||
- однонаправленного server-to-client прогресса;
|
||||
- проксирования;
|
||||
- reconnect semantics;
|
||||
- дебага и совместимости с обычными HTTP-инструментами.
|
||||
|
||||
WebSocket нужен не UI в первую очередь, а local worker transport.
|
||||
|
||||
## Consequences
|
||||
|
||||
`GET /tasks/{id}/events` фиксируется как SSE endpoint.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# ADR 004: Local Worker Transport
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Local Worker работает на машине пользователя и должен:
|
||||
|
||||
- сам инициировать соединение;
|
||||
- не требовать входящего порта на пользовательском ПК;
|
||||
- поддерживать прогресс, heartbeat и dispatch commands.
|
||||
|
||||
## Decision
|
||||
|
||||
Основной transport для worker gateway: outbound WebSocket session от worker к серверу.
|
||||
|
||||
## Required Semantics
|
||||
|
||||
- registration handshake;
|
||||
- capability advertisement;
|
||||
- heartbeat;
|
||||
- command dispatch;
|
||||
- progress events;
|
||||
- result envelope;
|
||||
- cancellation;
|
||||
- reconnect with new session id.
|
||||
|
||||
## Consequences
|
||||
|
||||
Worker transport остается отдельным delivery/infrastructure adapter и не врастает в orchestration core.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# ADR 005: Policy Evaluation Model
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Ключевой принцип проекта: без hardcoded bans.
|
||||
Система должна принимать решения через policy engine, а не через встроенные запреты по имени tool или по содержимому команды.
|
||||
|
||||
## Decision
|
||||
|
||||
Policy engine работает в 4 шага:
|
||||
|
||||
1. request/action нормализуется в `ActionDescriptor`;
|
||||
2. descriptor классифицируется по `resource` и `risk_level`;
|
||||
3. policy evaluator находит эффективное правило;
|
||||
4. возвращается `PolicyDecision`.
|
||||
|
||||
## Core Types
|
||||
|
||||
`resource`:
|
||||
|
||||
- `filesystem`
|
||||
- `shell`
|
||||
- `sql`
|
||||
- `mcp`
|
||||
- `external_models`
|
||||
- `desktop`
|
||||
- `browser`
|
||||
- `network`
|
||||
- `cost`
|
||||
- `system`
|
||||
|
||||
`risk_level`:
|
||||
|
||||
- `safe`
|
||||
- `write`
|
||||
- `destructive`
|
||||
- `system`
|
||||
- `cost`
|
||||
|
||||
`decision`:
|
||||
|
||||
- `allow`
|
||||
- `confirm`
|
||||
- `manual`
|
||||
- `disabled_by_config`
|
||||
|
||||
## Important Rule
|
||||
|
||||
Policy engine не получает “tool name only” как источник истины.
|
||||
Он должен опираться на action classification и metadata от tool/model/worker adapters.
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# ADR 006: Event Taxonomy And Correlation
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
Оркестратор должен быть отлаживаемым и воспроизводимым.
|
||||
Для этого все значимые переходы должны иметь единый event model.
|
||||
|
||||
## Decision
|
||||
|
||||
Все события включают:
|
||||
|
||||
- `event_id`
|
||||
- `event_type`
|
||||
- `occurred_at`
|
||||
- `task_id`
|
||||
- `conversation_id` when available
|
||||
- `node_id` when available
|
||||
- `correlation_id`
|
||||
- `causation_id`
|
||||
- `payload`
|
||||
|
||||
## Event Families
|
||||
|
||||
1. Task lifecycle
|
||||
2. Node lifecycle
|
||||
3. Policy decisions
|
||||
4. Confirmation lifecycle
|
||||
5. Model invocation lifecycle
|
||||
6. Tool invocation lifecycle
|
||||
7. Worker session lifecycle
|
||||
8. Worker command lifecycle
|
||||
9. Finalizer/result lifecycle
|
||||
10. System warnings/errors
|
||||
|
||||
## Consequences
|
||||
|
||||
UI, audit log, replay tooling и debugging должны читать одну и ту же taxonomy, а не разрозненные лог-сообщения.
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# ADR 007: Model Router Fallback Semantics
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
В проекте уже зафиксирована идея:
|
||||
|
||||
- сначала weak;
|
||||
- затем retry weak;
|
||||
- затем strong fallback;
|
||||
- external models не запрещаются кодом, а регулируются конфигом и policy.
|
||||
|
||||
## Decision
|
||||
|
||||
Fallback pipeline:
|
||||
|
||||
1. slot resolution выбирает provider и model для requested slot;
|
||||
2. weak model вызывается первой;
|
||||
3. если ответ невалиден по output contract, выполняется ограниченный retry weak;
|
||||
4. если weak исчерпан, router проверяет доступность strong;
|
||||
5. если strong разрешен config+policy, выполняется strong fallback;
|
||||
6. если strong недоступен, возвращается structured degraded result.
|
||||
|
||||
## Notes
|
||||
|
||||
- “невалиден” означает нарушение response schema, parser failure или явный quality rejection;
|
||||
- fallback trail сохраняется в invocation log;
|
||||
- внешняя strong model не вызывается, если `allow_external_models=false` или policy запрещает.
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
# Доменная модель
|
||||
|
||||
## Слои
|
||||
|
||||
### Domain
|
||||
|
||||
Чистые сущности, value objects, state machines, классификация рисков, события.
|
||||
|
||||
### Application
|
||||
|
||||
Use cases:
|
||||
|
||||
- create_task
|
||||
- submit_chat_message
|
||||
- plan_task
|
||||
- execute_ready_nodes
|
||||
- request_confirmation
|
||||
- approve_confirmation
|
||||
- reject_confirmation
|
||||
- register_worker
|
||||
- ingest_worker_result
|
||||
|
||||
### Infrastructure
|
||||
|
||||
- storage adapters
|
||||
- config loader
|
||||
- event publisher
|
||||
- model providers
|
||||
- MCP transport
|
||||
- worker gateway
|
||||
- artifact persistence
|
||||
|
||||
### Delivery
|
||||
|
||||
- HTTP API
|
||||
- SSE task events
|
||||
- worker WebSocket session endpoint
|
||||
|
||||
## Главные сущности
|
||||
|
||||
### ProjectConfig
|
||||
|
||||
Описывает:
|
||||
|
||||
- model slots
|
||||
- policy modes
|
||||
- execution limits
|
||||
- enabled MCP servers
|
||||
- worker access rules
|
||||
|
||||
### Conversation
|
||||
|
||||
Контейнер пользовательского диалога и связанных задач.
|
||||
|
||||
### Task
|
||||
|
||||
Единица выполнения пользовательской цели.
|
||||
|
||||
Поля:
|
||||
|
||||
- `id`
|
||||
- `project_id`
|
||||
- `conversation_id`
|
||||
- `goal`
|
||||
- `inputs`
|
||||
- `status`
|
||||
- `requested_mode`
|
||||
- `effective_mode`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
- `result_summary`
|
||||
|
||||
### ExecutionGraph
|
||||
|
||||
Набор node definitions и execution dependencies для конкретной task.
|
||||
|
||||
### Node
|
||||
|
||||
Типы:
|
||||
|
||||
- `planner`
|
||||
- `model_call`
|
||||
- `tool_call`
|
||||
- `local_worker_call`
|
||||
- `reviewer`
|
||||
- `finalizer`
|
||||
- `confirmation`
|
||||
|
||||
### ConfirmationRequest
|
||||
|
||||
Отдельная сущность для действий, требующих подтверждения.
|
||||
|
||||
### WorkerSession
|
||||
|
||||
Онлайн-сессия thin local worker.
|
||||
|
||||
### ModelInvocation
|
||||
|
||||
Record вызова model router/provider.
|
||||
|
||||
### ToolInvocation
|
||||
|
||||
Record вызова MCP tool или worker command.
|
||||
|
||||
### Artifact
|
||||
|
||||
Материализованный результат: patch, file diff, report, log bundle.
|
||||
|
||||
### Event
|
||||
|
||||
Audit и UI-событие в единой taxonomy.
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# State Machines
|
||||
|
||||
## TaskStatus
|
||||
|
||||
```text
|
||||
created
|
||||
-> planned
|
||||
-> running
|
||||
-> waiting_confirmation
|
||||
-> waiting_manual
|
||||
-> completed
|
||||
-> failed
|
||||
-> cancelled
|
||||
```
|
||||
|
||||
Правила:
|
||||
|
||||
- `created -> planned`: planner graph создан;
|
||||
- `planned -> running`: есть готовые к исполнению nodes;
|
||||
- `running -> waiting_confirmation`: execution остановлен на pending approval;
|
||||
- `running -> waiting_manual`: policy/manual gate остановил автостарт;
|
||||
- `running -> completed`: finalizer сформировал итог;
|
||||
- `running -> failed`: unrecoverable error;
|
||||
- `waiting_confirmation -> running`: approval получен;
|
||||
- `waiting_manual -> running`: пользователь вручную продолжил выполнение.
|
||||
|
||||
## NodeStatus
|
||||
|
||||
```text
|
||||
pending
|
||||
-> ready
|
||||
-> running
|
||||
-> waiting_confirmation
|
||||
-> completed
|
||||
-> failed
|
||||
-> skipped
|
||||
-> cancelled
|
||||
```
|
||||
|
||||
## ConfirmationStatus
|
||||
|
||||
```text
|
||||
pending
|
||||
-> approved
|
||||
-> rejected
|
||||
-> expired
|
||||
-> cancelled
|
||||
```
|
||||
|
||||
## WorkerSessionStatus
|
||||
|
||||
```text
|
||||
connecting
|
||||
-> online
|
||||
-> busy
|
||||
-> stale
|
||||
-> disconnected
|
||||
```
|
||||
|
||||
## Retry Principles
|
||||
|
||||
- retry выполняется только для явно retryable failures;
|
||||
- retry history фиксируется в node attempts и event log;
|
||||
- confirmation-required state не считается failure;
|
||||
- idempotency must be explicit for side-effecting nodes.
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# Internal Interfaces
|
||||
|
||||
## Orchestrator Application Ports
|
||||
|
||||
### TaskRepository
|
||||
|
||||
- create task
|
||||
- update task
|
||||
- get task by id
|
||||
- list active tasks
|
||||
|
||||
### GraphRepository
|
||||
|
||||
- save graph
|
||||
- get graph
|
||||
- update node state
|
||||
- list ready nodes
|
||||
|
||||
### ConfirmationRepository
|
||||
|
||||
- create confirmation
|
||||
- get confirmation
|
||||
- resolve confirmation
|
||||
|
||||
### WorkerRepository
|
||||
|
||||
- register session
|
||||
- update heartbeat
|
||||
- assign command
|
||||
- complete command
|
||||
|
||||
### EventStore
|
||||
|
||||
- append event
|
||||
- list events by task
|
||||
|
||||
### PolicyEvaluator
|
||||
|
||||
- evaluate action descriptor against project policy
|
||||
|
||||
### ModelRouter
|
||||
|
||||
- execute model request and return structured invocation result
|
||||
|
||||
### ToolGateway
|
||||
|
||||
- call MCP tool and return normalized result
|
||||
|
||||
### WorkerGateway
|
||||
|
||||
- dispatch command to worker and receive normalized result
|
||||
|
||||
## Design Rule
|
||||
|
||||
Application services зависят только от этих портов.
|
||||
Ни один use case не должен напрямую импортировать HTTP handlers, DB session objects или конкретный MCP/WebSocket client.
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# Error Model
|
||||
|
||||
## Error Families
|
||||
|
||||
### ValidationError
|
||||
|
||||
Некорректный вход, schema mismatch, invalid command envelope.
|
||||
|
||||
### PolicyError
|
||||
|
||||
Действие запрещено текущей конфигурацией или требует manual/confirm остановки.
|
||||
|
||||
### RetryableInfrastructureError
|
||||
|
||||
Временная ошибка транспорта, timeout, transient upstream failure.
|
||||
|
||||
### NonRetryableInfrastructureError
|
||||
|
||||
Постоянная ошибка конфигурации, unsupported capability, broken contract.
|
||||
|
||||
### ExecutionError
|
||||
|
||||
Ошибка бизнес-исполнения конкретного node.
|
||||
|
||||
### CancellationError
|
||||
|
||||
Task или node остановлены по explicit cancel.
|
||||
|
||||
## User-Facing Behavior
|
||||
|
||||
- validation и policy ошибки должны быть ясными и краткими;
|
||||
- infra ошибки должны сохранять technical details в logs/events;
|
||||
- task итог должен различать `failed` и `waiting for action`.
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
# Execution Model
|
||||
|
||||
## Базовый цикл
|
||||
|
||||
1. Пользователь создает `Task`.
|
||||
2. Planner materializes `ExecutionGraph`.
|
||||
3. Graph engine отмечает `ready` узлы.
|
||||
4. Orchestrator выбирает runner для каждого ready node.
|
||||
5. Перед side-effecting action выполняется policy evaluation.
|
||||
6. Если нужен `confirm`, создается `ConfirmationRequest` и graph останавливается.
|
||||
7. Если action разрешен, runner выполняет node.
|
||||
8. Node результат сохраняется как output + event trail + optional artifacts.
|
||||
9. Reviewer может валидировать промежуточный результат.
|
||||
10. Finalizer формирует user-facing result и cards.
|
||||
|
||||
## Node Families
|
||||
|
||||
### Planner
|
||||
|
||||
Создает или пересобирает graph. Не выполняет side effects.
|
||||
|
||||
### Model Call
|
||||
|
||||
Использует `ModelRouter`.
|
||||
Может инициировать fallback, но только внутри router contract.
|
||||
|
||||
### Tool Call
|
||||
|
||||
Использует `ToolGateway` для MCP.
|
||||
|
||||
### Local Worker Call
|
||||
|
||||
Использует `WorkerGateway` для thin executor.
|
||||
|
||||
### Reviewer
|
||||
|
||||
Системный шаг quality gate:
|
||||
|
||||
- schema validation
|
||||
- semantic validation
|
||||
- retry recommendation
|
||||
- escalate to strong model
|
||||
|
||||
### Finalizer
|
||||
|
||||
Преобразует execution result в user result:
|
||||
|
||||
- message text
|
||||
- cards
|
||||
- artifacts metadata
|
||||
- summary
|
||||
|
||||
## Execution Rules
|
||||
|
||||
- workers не создают новые workers;
|
||||
- model/router adapters не меняют graph напрямую;
|
||||
- только orchestrator меняет task/node state;
|
||||
- side effects всегда проходят через policy decision;
|
||||
- event log пишется на каждом значимом переходе.
|
||||
|
||||
## Manual And Resume
|
||||
|
||||
`manual` означает, что orchestrator не стартует следующий шаг автоматически.
|
||||
Task остается в `waiting_manual` до явного resume action.
|
||||
|
||||
## Replay
|
||||
|
||||
Replay не означает повтор side effects автоматически.
|
||||
Replay должен уметь:
|
||||
|
||||
- восстанавливать graph state из persisted state;
|
||||
- переиздавать progress view;
|
||||
- запускать retry только для разрешенных retryable nodes.
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# Execution Backlog
|
||||
|
||||
## Package A: Architecture Freeze
|
||||
|
||||
- [x] runtime ADR
|
||||
- [x] storage ADR
|
||||
- [x] event stream ADR
|
||||
- [x] worker transport ADR
|
||||
- [x] policy evaluation ADR
|
||||
- [x] event taxonomy ADR
|
||||
- [x] model fallback ADR
|
||||
- [x] domain model
|
||||
- [x] state machines
|
||||
- [x] storage schema draft
|
||||
- [x] internal interfaces
|
||||
- [x] error model
|
||||
- [x] execution model
|
||||
|
||||
## Package B: Core Hardening
|
||||
|
||||
- [ ] graph scheduler service
|
||||
- [ ] node runner abstraction
|
||||
- [ ] reviewer contract
|
||||
- [ ] finalizer contract
|
||||
- [ ] resume/cancel use cases
|
||||
- [ ] idempotency policy
|
||||
- [ ] retry policy matrix
|
||||
|
||||
## Package C: Persistence
|
||||
|
||||
- [ ] SQLAlchemy models
|
||||
- [ ] repositories for PostgreSQL/SQLite
|
||||
- [ ] migrations
|
||||
- [ ] artifact metadata persistence
|
||||
- [ ] event store queries with pagination
|
||||
|
||||
## Package D: Integrations
|
||||
|
||||
- [ ] model router providers
|
||||
- [ ] MCP transport adapter
|
||||
- [ ] worker WebSocket gateway
|
||||
- [ ] heartbeat monitor
|
||||
- [ ] capability-aware dispatch
|
||||
|
||||
## Package E: Delivery
|
||||
|
||||
- [ ] typed worker registration schema
|
||||
- [ ] task event DTO normalization
|
||||
- [ ] confirmation cards
|
||||
- [ ] progress cards
|
||||
- [ ] artifact cards
|
||||
- [ ] error cards
|
||||
|
||||
## Package F: Validation
|
||||
|
||||
- [ ] contract tests
|
||||
- [ ] scenario tests
|
||||
- [ ] smoke suite
|
||||
- [ ] static checks in CI
|
||||
|
||||
@@ -59,7 +59,9 @@
|
||||
|
||||
## GET /tasks/{task_id}/events
|
||||
|
||||
SSE/WebSocket stream событий:
|
||||
Primary transport: SSE stream событий.
|
||||
|
||||
WebSocket может быть добавлен как secondary adapter, но contract-first путь для UI: SSE.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -87,6 +89,24 @@ SSE/WebSocket stream событий:
|
||||
}
|
||||
```
|
||||
|
||||
## GET /workers
|
||||
|
||||
Список известных worker sessions.
|
||||
|
||||
```json
|
||||
{
|
||||
"workers": [
|
||||
{
|
||||
"session_id": "wrk_1",
|
||||
"worker_id": "worker_home_pc",
|
||||
"name": "Home PC",
|
||||
"status": "online",
|
||||
"capabilities": ["file.read", "command.run"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## POST /workers/register
|
||||
|
||||
Local worker регистрируется на сервере.
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
# Persistent Storage Schema Draft
|
||||
|
||||
## Database Target
|
||||
|
||||
- production: PostgreSQL
|
||||
- local development: SQLite
|
||||
|
||||
## Tables
|
||||
|
||||
### projects
|
||||
|
||||
- `project_id` pk
|
||||
- `name`
|
||||
- `config_blob`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
### conversations
|
||||
|
||||
- `conversation_id` pk
|
||||
- `project_id`
|
||||
- `title`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
### messages
|
||||
|
||||
- `message_id` pk
|
||||
- `conversation_id`
|
||||
- `role`
|
||||
- `content`
|
||||
- `attachments_json`
|
||||
- `created_at`
|
||||
|
||||
### tasks
|
||||
|
||||
- `task_id` pk
|
||||
- `project_id`
|
||||
- `conversation_id`
|
||||
- `goal`
|
||||
- `inputs_json`
|
||||
- `status`
|
||||
- `requested_mode`
|
||||
- `effective_mode`
|
||||
- `current_node_id`
|
||||
- `result_summary_json`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
### task_graphs
|
||||
|
||||
- `task_id` pk
|
||||
- `graph_version`
|
||||
- `graph_metadata_json`
|
||||
- `created_at`
|
||||
|
||||
### task_nodes
|
||||
|
||||
- `node_id` pk
|
||||
- `task_id`
|
||||
- `node_type`
|
||||
- `status`
|
||||
- `input_json`
|
||||
- `output_json`
|
||||
- `dependencies_json`
|
||||
- `assigned_runner`
|
||||
- `attempts`
|
||||
- `retryable`
|
||||
- `timeout_ms`
|
||||
- `created_at`
|
||||
- `updated_at`
|
||||
|
||||
### task_events
|
||||
|
||||
- `event_id` pk
|
||||
- `task_id`
|
||||
- `conversation_id`
|
||||
- `node_id`
|
||||
- `event_type`
|
||||
- `correlation_id`
|
||||
- `causation_id`
|
||||
- `payload_json`
|
||||
- `occurred_at`
|
||||
|
||||
### confirmations
|
||||
|
||||
- `confirmation_id` pk
|
||||
- `task_id`
|
||||
- `node_id`
|
||||
- `status`
|
||||
- `scope`
|
||||
- `decision_json`
|
||||
- `preview_json`
|
||||
- `comment`
|
||||
- `created_at`
|
||||
- `resolved_at`
|
||||
|
||||
### worker_sessions
|
||||
|
||||
- `session_id` pk
|
||||
- `worker_id`
|
||||
- `name`
|
||||
- `machine`
|
||||
- `os`
|
||||
- `version`
|
||||
- `status`
|
||||
- `capabilities_json`
|
||||
- `last_heartbeat_at`
|
||||
- `current_task_id`
|
||||
- `connected_at`
|
||||
- `disconnected_at`
|
||||
|
||||
### model_invocations
|
||||
|
||||
- `invocation_id` pk
|
||||
- `task_id`
|
||||
- `node_id`
|
||||
- `slot`
|
||||
- `provider`
|
||||
- `model`
|
||||
- `status`
|
||||
- `request_json`
|
||||
- `response_json`
|
||||
- `usage_json`
|
||||
- `fallback_from_invocation_id`
|
||||
- `created_at`
|
||||
|
||||
### tool_invocations
|
||||
|
||||
- `invocation_id` pk
|
||||
- `task_id`
|
||||
- `node_id`
|
||||
- `source_type`
|
||||
- `source_id`
|
||||
- `tool_name`
|
||||
- `status`
|
||||
- `request_json`
|
||||
- `response_json`
|
||||
- `created_at`
|
||||
|
||||
### artifacts
|
||||
|
||||
- `artifact_id` pk
|
||||
- `task_id`
|
||||
- `node_id`
|
||||
- `artifact_type`
|
||||
- `storage_uri`
|
||||
- `metadata_json`
|
||||
- `created_at`
|
||||
|
||||
## Required Indexes
|
||||
|
||||
- `tasks(status, updated_at)`
|
||||
- `task_nodes(task_id, status)`
|
||||
- `task_events(task_id, occurred_at)`
|
||||
- `confirmations(status, created_at)`
|
||||
- `worker_sessions(status, last_heartbeat_at)`
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Testing Strategy
|
||||
|
||||
## Layers
|
||||
|
||||
### Unit Tests
|
||||
|
||||
- state transitions
|
||||
- policy evaluation
|
||||
- graph readiness
|
||||
- fallback logic
|
||||
|
||||
### Contract Tests
|
||||
|
||||
- API schemas
|
||||
- worker envelopes
|
||||
- MCP result normalization
|
||||
- model router output contracts
|
||||
|
||||
### Integration Tests
|
||||
|
||||
- repository implementations
|
||||
- event streaming
|
||||
- config loader
|
||||
- storage adapters
|
||||
|
||||
### Scenario Tests
|
||||
|
||||
- create task -> plan -> execute -> finalize
|
||||
- confirm flow
|
||||
- weak retry then strong fallback
|
||||
- worker result ingestion
|
||||
|
||||
### Smoke Tests
|
||||
|
||||
Обязательный список зафиксирован в [tests/smoke/SMOKE_TESTS.md](/Z:/codex/ai_orchestrator/tests/smoke/SMOKE_TESTS.md).
|
||||
|
||||
Reference in New Issue
Block a user