Implement the owner-scoped byte cache service and read/control API: cache lookup, retain, pin/release, per-user LRU eviction, quota accounting, settings update, and metadata-safe cache status responses.
Scope fence: do not wire analysis workers or open/preview hydration yet. This plan builds the cache primitive those paths will call.
@.planning/phases/14-selective-analysis-and-byte-cache/14-RESEARCH.md
@.planning/phases/14-selective-analysis-and-byte-cache/14-PATTERNS.md
@backend/storage/minio_backend.py
@backend/services/cloud_items.py
@backend/db/models.py
@backend/api/cloud/schemas.py
Task 1: Build cache service with quota and pinning semantics
backend/services/cloud_byte_cache.py, backend/tests/test_cloud_cache.py
- backend/storage/minio_backend.py
- backend/services/quota.py
- backend/db/models.py
- backend/tests/test_quota.py
Add cache service functions to resolve owned cache entries, reserve quota atomically before retaining bytes, store bytes using UUID/private object keys, record metadata, reuse matching non-evicted version entries, pin/release active job or preview use, update last access, evict inactive LRU entries per user limit, decrement quota when retained bytes are evicted, and delete MinIO objects best-effort after DB state is consistent. Protect entries with `pin_count > 0` or `active_job_count > 0`.
- Cache retention increments quota and eviction decrements quota with atomic quota helpers.
- Eviction never selects another user's entry and never evicts pinned/active entries.
- Object keys are generated UUID/private keys and never include provider filenames.
- Service functions raise domain errors or `ValueError`, never `HTTPException`.
cd backend && pytest -q tests/test_cloud_cache.py
Task 2: Add cache settings/status API
backend/api/cloud/cache.py, backend/api/cloud/schemas.py, backend/api/cloud/__init__.py, backend/tests/test_cloud_cache.py, backend/tests/test_cloud_security.py
- backend/api/cloud/connections.py
- backend/api/cloud/operations.py
- backend/api/cloud/schemas.py
- backend/tests/test_cloud_security.py
Add credential-free endpoints for current cache usage/settings and updating the user's preferred cache limit/progress/failure settings. Use explicit Pydantic fields only. Return aggregate bytes/counts and tier cap, not object keys. Enforce `get_regular_user`, owner scope, and rate limiting consistent with existing cloud routes.
- Admin users are blocked.
- Responses contain no `object_key`, credentials, raw provider URLs, or extracted text.
- Invalid cache limits above the tier/admin cap return a controlled validation response.
- Security tests cover foreign user and admin-negative cases.
cd backend && pytest -q tests/test_cloud_cache.py tests/test_cloud_security.py -k "cache"
<threat_model>
Threat ID
Threat
Mitigation
T-14-06
Cross-user cache access
All cache entry queries include user_id and connection_id; negative tests
T-14-07
Quota race
Existing atomic quota update helpers required for retain/evict deltas
T-14-08
Object key leakage
API schemas omit object_key and tests assert absence
T-14-09
Active work eviction
Pin/active counters in selection predicate and regression tests