Files
crank/docs/streaming-implementation-spec.md
T
2026-04-06 09:40:59 +03:00

585 lines
17 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.
# Streaming Implementation Specification
## 1. Назначение документа
Этот документ переводит streaming architecture в execution-oriented plan, пригодный для агентной разработки.
Он отвечает на вопросы:
- в каком порядке реализовывать фичи;
- какие файлы менять в каждом срезе;
- какие новые модули создавать;
- какие тесты обязательны;
- какие риски и зависимости есть между срезами;
- какой Definition of Done нужен для каждого шага.
Документ дополняет:
- [streaming-mcp-plan.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-mcp-plan.md)
- [streaming-admin-api.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-admin-api.md)
- [streaming-runtime-design.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-runtime-design.md)
- [streaming-ui-contract.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-ui-contract.md)
- [protocol-capability-matrix.md](/home/a.tolmachev/code/rust/mcpaas/docs/protocol-capability-matrix.md)
## 2. Принципы агентной реализации
- один vertical slice на ветку;
- docs first, code second;
- не смешивать transport alignment, core model, registry, runtime и UI в одном срезе;
- каждый срез должен быть протестирован отдельно;
- stateful streaming нельзя вводить через скрытые side effects;
- session/job lifecycle должен появляться в коде и API явно.
## 3. Dependency graph
Порядок реализации:
1. `feat/mcp-streamable-http-alignment`
2. `feat/streaming-core-model`
3. `feat/stream-session-store`
4. `feat/runtime-window-mode`
5. `feat/rest-sse-adapter`
6. `feat/grpc-server-streaming-adapter`
7. `feat/session-and-job-tools`
8. `feat/streaming-ui-config`
9. `feat/streaming-e2e`
10. `feat/websocket-upstream-adapter`
11. `feat/soap-architecture-and-core-model`
12. `feat/soap-adapter-foundation`
Почему именно так:
- сначала transport correctness;
- потом core types;
- потом persistence;
- потом bounded runtime;
- потом protocol adapters;
- потом MCP tool publishing;
- потом UI;
- потом e2e;
- потом расширение protocol platform.
## 4. Slice 1: `feat/mcp-streamable-http-alignment`
### 4.1. Цель
Довести `apps/mcp-server` до полного и явного соответствия MCP `Streamable HTTP`.
### 4.2. Файлы
Изменить:
- [apps/mcp-server/src/app.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/app.rs)
- [apps/mcp-server/src/jsonrpc.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/jsonrpc.rs)
- [apps/mcp-server/src/session.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/session.rs)
- [apps/mcp-server/src/main.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/main.rs)
Добавить при необходимости:
- `apps/mcp-server/src/transport.rs`
- `apps/mcp-server/src/sse.rs`
### 4.3. Что должно быть сделано
- parse `Accept` корректно для `application/json` и `text/event-stream`;
- `GET` endpoint перестает быть `405` и становится SSE-capable transport stream;
- `POST` может отвечать JSON или SSE в зависимости от negotiated transport;
- `Mcp-Session-Id` создается, читается и валидируется явно;
- `MCP-Protocol-Version` валидируется и возвращается явно;
- `DELETE` корректно завершает transport session;
- disconnect не трактуется как cancel operation.
### 4.4. Тесты
Обязательно добавить:
- initialize через JSON response;
- initialize через SSE response;
- `GET` SSE handshake;
- повторное использование `Mcp-Session-Id`;
- invalid protocol version;
- invalid accept header;
- session close through `DELETE`.
### 4.5. DoD
- `mcp-server` ведет себя согласно spec;
- transport tests зелёные;
- docs и code names совпадают.
## 5. Slice 2: `feat/streaming-core-model`
### 5.1. Цель
Ввести доменные типы streaming execution.
### 5.2. Файлы
Изменить:
- [crates/crank-core/src/lib.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/lib.rs)
- [crates/crank-core/src/operation.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/operation.rs)
- [crates/crank-core/src/ids.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/ids.rs)
- [crates/crank-core/src/protocol.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/protocol.rs)
Добавить:
- `crates/crank-core/src/streaming.rs`
- `crates/crank-core/src/stream_session.rs`
### 5.3. Что должно быть сделано
- добавить `ExecutionMode`;
- добавить `TransportBehavior`;
- добавить `AggregationMode`;
- добавить `StreamingConfig`;
- добавить `StreamSessionId`, `AsyncJobId`;
- добавить `StreamSession`, `AsyncJobHandle`, `StreamStatus`, `JobStatus`;
- вшить `streaming: Option<StreamingConfig>` в `ExecutionConfig`.
### 5.4. Тесты
- serde roundtrip для `StreamingConfig`;
- validation rules для `ExecutionMode`;
- protocol-aware validation helpers.
### 5.5. DoD
- core types стабильны;
- экспортированы через `lib.rs`;
- naming не спорит с docs.
## 6. Slice 3: `feat/stream-session-store`
### 6.1. Цель
Добавить persistent store для `stream_sessions` и `async_jobs`.
### 6.2. Файлы
Изменить:
- [crates/crank-registry/src/lib.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/lib.rs)
- [crates/crank-registry/src/model.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/model.rs)
- [crates/crank-registry/src/migrations.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/migrations.rs)
- [crates/crank-registry/src/postgres.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/postgres.rs)
### 6.3. Что должно быть сделано
- таблицы `stream_sessions`, `async_jobs`;
- record types;
- create/get/update/close/list/delete-expired methods;
- filters and paging;
- optimistic transitions для state updates.
### 6.4. Тесты
- migration test;
- create/get/update/close session;
- create/get/update/cancel async job;
- cleanup expired rows;
- invalid transition rejection.
### 6.5. DoD
- storage API соответствует runtime design;
- transitions не допускают silent corruption.
## 7. Slice 4: `feat/runtime-window-mode`
### 7.1. Цель
Ввести bounded `window` mode до session/job complexity.
### 7.2. Файлы
Изменить:
- [crates/crank-runtime/src/lib.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/lib.rs)
- [crates/crank-runtime/src/model.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/model.rs)
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
- [crates/crank-runtime/src/error.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/error.rs)
Добавить:
- `crates/crank-runtime/src/streaming.rs`
- `crates/crank-runtime/src/aggregation.rs`
- `crates/crank-runtime/src/redaction.rs`
### 7.3. Что должно быть сделано
- `execute_window_operation`;
- bounded item/byte limiting;
- `truncated`, `window_complete`, `has_more`;
- summary building;
- redaction and truncation;
- observability write.
### 7.4. Тесты
- raw items mode;
- summary only mode;
- summary plus samples;
- max item truncation;
- max byte truncation;
- redaction;
- timeout handling.
### 7.5. DoD
- unary execution не ломается;
- window mode работает для synthetic adapter-level fixtures.
## 8. Slice 5: `feat/rest-sse-adapter`
### 8.1. Цель
Добавить bounded REST SSE support.
### 8.2. Файлы
Изменить:
- текущий crate [crates/crank-adapter-rest](/home/a.tolmachev/code/rust/mcpaas/crates/crank-adapter-rest)
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
Ожидаемые файлы:
- `src/lib.rs`
- `src/error.rs`
- `src/client.rs`
- `src/sse.rs`
### 8.3. Что должно быть сделано
- SSE connect;
- event parsing;
- bounded collect window;
- session start/poll/stop hooks, если adapter slice сразу включает stateful mode;
- proper close.
### 8.4. Тесты
- local SSE upstream fixture;
- collect N events;
- timeout without events;
- malformed event handling;
- reconnect not enabled by default.
## 9. Slice 6: `feat/grpc-server-streaming-adapter`
### 9.1. Цель
Добавить bounded gRPC server-streaming.
### 9.2. Файлы
Изменить:
- [crates/crank-adapter-grpc](/home/a.tolmachev/code/rust/mcpaas/crates/crank-adapter-grpc)
- [crates/crank-proto](/home/a.tolmachev/code/rust/mcpaas/crates/crank-proto)
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
### 9.3. Что должно быть сделано
- identify unary vs server-streaming method from descriptors;
- invoke server stream;
- collect bounded window;
- decode stream items to normalized JSON;
- integrate with window mode.
### 9.4. Тесты
- local grpc fixture with server-streaming;
- descriptor-backed invocation;
- bounded collection;
- timeout;
- malformed item handling.
## 10. Slice 7: `feat/session-and-job-tools`
### 10.1. Цель
Ввести `session` и `async_job` как first-class runtime and MCP constructs.
### 10.2. Файлы
Изменить:
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
- [apps/mcp-server/src/app.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/app.rs)
- [apps/mcp-server/src/catalog.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/catalog.rs)
- [apps/mcp-server/src/session.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/session.rs)
- [crates/crank-registry/src/postgres.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/postgres.rs)
### 10.3. Что должно быть сделано
- runtime methods for start/poll/stop and start/status/result/cancel;
- MCP tool-family generation;
- binding-level tool-name derivation;
- JSON-RPC call routing for tool families;
- session/job observability.
### 10.4. Тесты
- tool listing shows generated family;
- `session start -> poll -> stop`;
- `async_job start -> status -> result -> cancel`;
- invalid session id;
- expired session;
- result before ready.
## 11. Slice 8: `feat/streaming-ui-config`
### 11.1. Цель
Добавить UI для streaming configuration.
### 11.2. Файлы
Изменить:
- `apps/ui/html/wizard/*.html`
- `apps/ui/js/wizard.js`
- `apps/ui/js/api.js`
- `apps/ui/js/i18n.js`
- CSS файлы wizard/settings/pages по необходимости
Добавить:
- `apps/ui/js/streaming-form.js`
- `apps/ui/js/stream-test-run.js`
- `apps/ui/html/stream-sessions.html`
- `apps/ui/html/async-jobs.html`
### 11.3. Что должно быть сделано
- protocol capabilities fetch;
- execution mode selector;
- protocol-specific field visibility;
- validation wiring;
- test-run UX for window/session/async job;
- sessions/jobs views;
- localization.
### 11.4. Тесты
- Playwright:
- configure REST window;
- configure gRPC streaming;
- validation error render;
- session test flow;
- async job test flow.
## 12. Slice 9: `feat/streaming-e2e`
### 12.1. Цель
Зафиксировать end-to-end behavior на живом тестовом стеке.
### 12.2. Что должно быть сделано
- добавить local fixtures:
- REST SSE server
- gRPC server-streaming server
- WebSocket event server
- SOAP fixture, если adapter уже готов
- добавить smoke scenarios;
- включить их в CI.
### 12.3. Тесты
- tool call end-to-end through mcp-server;
- usage/logging on streaming calls;
- session cleanup;
- async job cleanup.
## 13. Slice 10: `feat/websocket-upstream-adapter`
### 13.1. Файлы
Добавить:
- `crates/crank-adapter-websocket/Cargo.toml`
- `crates/crank-adapter-websocket/src/lib.rs`
- `crates/crank-adapter-websocket/src/error.rs`
- `crates/crank-adapter-websocket/src/client.rs`
- `crates/crank-adapter-websocket/src/session.rs`
Изменить:
- [crates/crank-core/src/protocol.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/protocol.rs)
- [crates/crank-core/src/operation.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/operation.rs)
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
### 13.2. DoD
- bounded WebSocket window;
- session support;
- reconnect and heartbeat policy;
- capability matrix exposed in admin-api and UI.
## 14. Slice 11: `feat/soap-architecture-and-core-model`
### 14.1. Файлы
Изменить:
- [crates/crank-core/src/protocol.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/protocol.rs)
- [crates/crank-core/src/operation.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/operation.rs)
- [crates/crank-schema](/home/a.tolmachev/code/rust/mcpaas/crates/crank-schema)
Добавить:
- `crates/crank-core/src/soap.rs`
### 14.2. DoD
- SOAP target model;
- WSDL/XSD-derived metadata model;
- XML normalization strategy documented in code-level types.
## 15. Slice 12: `feat/soap-adapter-foundation`
### 15.1. Файлы
Добавить:
- `crates/crank-adapter-soap/Cargo.toml`
- `crates/crank-adapter-soap/src/lib.rs`
- `crates/crank-adapter-soap/src/error.rs`
- `crates/crank-adapter-soap/src/wsdl.rs`
- `crates/crank-adapter-soap/src/xml.rs`
- `crates/crank-adapter-soap/src/client.rs`
Изменить:
- `apps/admin-api`
- `apps/ui`
- `crates/crank-runtime`
### 15.2. DoD
- WSDL import;
- service/port/operation selection;
- SOAP request-response execution;
- fault normalization;
- UI test-run support.
## 16. State transition tables
## 16.1. `StreamSession`
Allowed:
- `created -> running`
- `running -> running`
- `running -> stopped`
- `running -> expired`
- `running -> failed`
- `stopped -> deleted`
- `expired -> deleted`
- `failed -> deleted`
Forbidden:
- `stopped -> running`
- `expired -> running`
- `deleted -> *`
## 16.2. `AsyncJob`
Allowed:
- `created -> running`
- `running -> running`
- `running -> completed`
- `running -> failed`
- `running -> cancelled`
- `completed -> expired`
- `failed -> expired`
- `cancelled -> expired`
Forbidden:
- `completed -> running`
- `cancelled -> running`
## 17. Sequence outlines
## 17.1. Window
1. MCP client calls tool.
2. `mcp-server` resolves tool binding.
3. `runtime.execute_window_operation`.
4. adapter collects bounded upstream data.
5. runtime aggregates and truncates.
6. `mcp-server` returns final JSON-RPC result.
## 17.2. Session
1. MCP client calls `{tool}_start`.
2. runtime starts upstream session and persists `StreamSession`.
3. client calls `{tool}_poll`.
4. runtime loads session and collects next bounded chunk.
5. client calls `{tool}_stop`.
6. runtime closes upstream and marks session stopped.
## 17.3. Async Job
1. MCP client calls `{tool}_start`.
2. runtime starts long-running job and persists `AsyncJob`.
3. client calls `{tool}_status`.
4. runtime returns current progress.
5. client calls `{tool}_result`.
6. runtime returns final normalized result if ready.
## 18. Acceptance checklist per slice
Перед merge каждого slice агент обязан проверить:
- docs updated if contract changed;
- `just fmt-check`
- `just check`
- `just clippy`
- `just test`
- relevant Playwright/e2e if UI touched;
- no hidden feature flags without docs;
- no unsupported combinations exposed in UI.
## 19. Branch and commit policy
Ожидаемые branch names:
- `feat/mcp-streamable-http-alignment`
- `feat/streaming-core-model`
- `feat/stream-session-store`
- `feat/runtime-window-mode`
- `feat/rest-sse-adapter`
- `feat/grpc-server-streaming-adapter`
- `feat/session-and-job-tools`
- `feat/streaming-ui-config`
- `feat/streaming-e2e`
- `feat/websocket-upstream-adapter`
- `feat/soap-architecture-and-core-model`
- `feat/soap-adapter-foundation`
Ожидаемые commit classes:
- `docs: ...`
- `feat: ...`
- `test: ...`
- `refactor: ...`
- `fix: ...`
## 20. Practical rule for agents
Агент не должен брать следующий slice, пока не выполнены DoD и тесты предыдущего slice.
Если slice требует новый contract:
1. обновить docs;
2. обновить tests;
3. обновить code;
4. только потом переходить дальше.