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

17 KiB
Raw Blame History

Streaming Implementation Specification

1. Назначение документа

Этот документ переводит streaming architecture в execution-oriented plan, пригодный для агентной разработки.

Он отвечает на вопросы:

  • в каком порядке реализовывать фичи;
  • какие файлы менять в каждом срезе;
  • какие новые модули создавать;
  • какие тесты обязательны;
  • какие риски и зависимости есть между срезами;
  • какой Definition of Done нужен для каждого шага.

Документ дополняет:

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/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/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. Файлы

Изменить:

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/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. Файлы

Изменить:

Ожидаемые файлы:

  • 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. Файлы

Изменить:

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. Файлы

Изменить:

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

Изменить:

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/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. только потом переходить дальше.