cache: add grpc read-only response caching

This commit is contained in:
a.tolmachev
2026-05-04 09:34:34 +00:00
parent b2c5e28cba
commit a61064ba3a
13 changed files with 306 additions and 91 deletions
+29 -78
View File
@@ -2,84 +2,6 @@
## Current
### `feat/optional-cache-layer`
Status: in_progress
Goal:
- добавить в продукт optional cache/coordination layer с `Valkey/Redis` backend без обязательной зависимости от него.
Main code areas:
- `crates/crank-core`
- `crates/crank-runtime`
- `apps/admin-api`
- `apps/mcp-server`
- `deploy/community/*`
- `docs/runtime-config.md`
- `docs/product-editions.md`
- `docs/commercial-boundaries.md`
Implementation slices:
1. Зафиксировать public cache contracts:
- response cache
- rate-limit store
- token replay / one-time token store
- ephemeral coordination state
2. Подготовить Community fallback path:
- без `Valkey/Redis` все должно работать
- degraded mode documented explicitly
3. Добавить optional `Valkey` service в Community deployment manifests как рекомендованный, но не обязательный runtime component.
4. Подготовить `Valkey/Redis` backend для:
- managed Cloud default
- enterprise optional cluster-aware deployment
5. Протянуть capability/config model так, чтобы решение "использовать или нет внешний cache" принимал оператор, а не кодовая база.
6. Зафиксировать safe cache boundaries:
- platform cache и response cache не смешиваются;
- ключи response cache изолируются минимум по `workspace + agent + operation + request fingerprint`;
- ключи coordination state изолируются минимум по `workspace + agent + cache scope`;
- при отсутствии внешнего cache все эти контуры продолжают работать через in-memory fallback.
7. Довести response cache не только до Community baseline, но и до первых коммерчески ценных read-only hot paths:
- `REST GET`
- `GraphQL query`
при сохранении той же изоляции и opt-in policy.
DoD:
- без `Valkey/Redis` Community и self-hosted deployment остаются рабочими;
- с `Valkey/Redis` платформа умеет снижать runtime/load pressure и хранить ephemeral coordination state;
- `Cloud` может использовать shared cache layer по умолчанию;
- `Enterprise` может подключать cache layer на своей инфраструктуре, включая кластерный вариант;
- runtime/docs/manifests не делают cache обязательным для базового запуска.
- cache boundaries и key namespaces документированы так, чтобы разные агенты и рабочие области не пересекались друг с другом.
- response cache покрывает первый коммерчески значимый protocol set без перехода к небезопасному "cache everything":
- `REST GET`
- `GraphQL query`
- дальнейшее расширение на `gRPC unary` возможно только для явно read-only / cacheable операций.
Verification:
- targeted runtime/admin/mcp tests for cache contracts and fallback mode;
- deploy manifest validation.
Progress:
- done:
- product/docs/runtime plan already define cache layer as optional and edition-aware
- public cache contracts and runtime cache config now exist in `crank-core` / `crank-runtime`
- Community fallback in-memory implementations now exist for response cache, rate-limit state, replay guard, and coordination state
- Community deployment manifest now includes optional `valkey` profile and cache env wiring without making cache mandatory
- shared `Valkey/Redis` backend layer now exists in `crank-runtime` with config-driven store factory for managed / enterprise contours
- admin-api and mcp-server ingress rate limiting now use shared external cache state when `CRANK_CACHE_BACKEND` is `valkey` or `redis`
- `ExecutionConfig.response_cache` is now part of the public operation model, and `admin-api` validates the safe Community baseline: only explicit `REST GET` operations without `auth_profile_ref`
- cache boundary and namespace rules are now documented for `platform / coordination cache` versus `response cache`
- runtime executor now performs actual response cache reads/writes for eligible `REST GET` operations with keys isolated by `workspace + agent + operation + request fingerprint`
- response cache keys now also include `operation version`, so a new published version does not reuse stale cached payloads from the previous one
- mcp-server published tool catalog now uses shared coordination snapshots across instances, while preserving the same `workspace + agent` isolation model
- response cache runtime/admin contracts now also cover `GraphQL query` as the first commercial protocol extension beyond the `REST GET` baseline
- pending:
- preserve the same isolation model while extending response cache to the next monetizable read-only path: explicit `gRPC unary` read operations
- wire replay guard into the first real token or nonce flow once commercial machine-token issuance stops being a `Community` stub
- wire coordination state into additional runtime or transport paths beyond the shared published catalog snapshot
## Planned
### `feat/open-core-repo-boundary`
Status: in_progress
@@ -127,6 +49,35 @@ Progress:
- remaining extension seams and packaging split still need to move from planning into concrete `crank-community` / `crank-enterprise` / `crank-cloud` manifests
- next management gate is to actually create the `3` target repositories before physical split starts
## Planned
### `feat/commercial-machine-token-flow`
Status: ready
Goal:
- реализовать короткоживущие и одноразовые машинные токены как коммерческий auth contour, а не как Community stub.
Main code areas:
- private `enterprise/cloud` token services
- public contracts already fixed in:
- `crates/crank-core`
- `apps/admin-api`
- `apps/mcp-server`
- `docs/agent-auth-model.md`
Implementation slices:
1. short-lived token issuance
2. one-time token issuance
3. replay guard / nonce coordination on top of cache layer
4. runtime verification and policy enforcement by `security_level`
5. capability-gated UI/admin flows for commercial editions
DoD:
- replay guard is no longer a stub abstraction and is wired into a real token flow;
- `elevated/strict` machine access works end-to-end in commercial contours;
- Community remains on static agent keys only.
### `feat/enterprise-access-governance`
Status: ready