Implement Phase 14 analysis estimate, enqueue, status, cancellation, skip, and retry APIs backed by durable job rows and idempotency checks.
Scope fence: enqueue and control jobs only. Actual provider byte hydration/extraction/classification is Plan 05.
@.planning/phases/14-selective-analysis-and-byte-cache/14-CONTEXT.md
@.planning/phases/14-selective-analysis-and-byte-cache/14-PATTERNS.md
@backend/services/cloud_items.py
@backend/services/cloud_analysis_versioning.py
@backend/services/cloud_analysis_settings.py
@backend/api/cloud/operations.py
Task 1: Add analysis orchestration service
backend/services/cloud_analysis.py, backend/tests/test_cloud_analysis_contract.py
- backend/services/cloud_items.py
- backend/services/cloud_analysis_versioning.py
- backend/db/models.py
Implement owner-scoped functions for estimating file/selection/folder/connection scopes, expanding known folder descendants from metadata where available, reporting partial estimates when provider expansion is incomplete, creating analysis jobs and job items, skipping unsupported/current items, and rejecting duplicate active jobs for the same user/item/version. Folder analysis must preserve current-only vs recursive choice; whole-connection analysis is recursive. Estimates never download bytes.
- File, selection, folder, and connection scope requests create correct job metadata.
- Whole-connection jobs require estimate acknowledgement unless trivially small by configured thresholds.
- Current unchanged items are marked `already_current` and do not enqueue byte work.
- Provider mutation methods are never called.
cd backend && pytest -q tests/test_cloud_analysis_contract.py
Task 2: Add analysis API routes and typed schemas
backend/api/cloud/analysis.py, backend/api/cloud/schemas.py, backend/api/cloud/__init__.py, backend/tests/test_cloud_analysis_api.py, backend/tests/test_cloud_security.py
- backend/api/cloud/operations.py
- backend/api/cloud/schemas.py
- backend/tests/test_cloud_security.py
Add routes under `/api/cloud/connections/{connection_id}/analysis` for estimate, enqueue/start, job status/list, cancel item, cancel batch, skip failed/queued item, and retry failed item. Use explicit request schemas and credential-free response schemas. Convert service domain errors into typed JSON bodies with stable `kind`/`reason` fields.
- Routes use `get_regular_user` and owner-scoped connection/item resolution.
- Status responses expose aggregate and per-item state without credentials, object keys, provider URLs, or raw provider errors.
- Retry creates a fresh item attempt from the beginning.
- Cancel queued work immediately and marks running work cancellation-requested for worker cooperation.
cd backend && pytest -q tests/test_cloud_analysis_api.py tests/test_cloud_security.py -k "analysis"
1. `cd backend && pytest -q tests/test_cloud_analysis_contract.py tests/test_cloud_analysis_api.py`
2. `cd backend && pytest -q tests/test_cloud_security.py -k "analysis"`
3. Confirm `rg "download|get_object|put_object" backend/services/cloud_analysis.py backend/api/cloud/analysis.py` has no estimate-time byte fetch.
Create .planning/phases/14-selective-analysis-and-byte-cache/14-04-SUMMARY.md when complete.