docs(13): add phase 13 planning artifacts — virtual local cloud operations
Plans 01–11, CONTEXT, PATTERNS, RESEARCH, REVIEW-FIX, and updated SUMMARY and CONTEXT for the virtual-local-cloud-operations phase. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
73328eee0b
commit
b67e77dd69
@@ -0,0 +1,174 @@
|
||||
---
|
||||
phase: "13"
|
||||
plan: "05"
|
||||
type: execute
|
||||
wave: 3
|
||||
depends_on:
|
||||
- "13-01"
|
||||
- "13-03"
|
||||
- "13-04"
|
||||
files_modified:
|
||||
- backend/api/cloud/operations.py
|
||||
- backend/api/cloud/schemas.py
|
||||
- backend/services/cloud_operations.py
|
||||
- backend/storage/google_drive_backend.py
|
||||
- backend/storage/onedrive_backend.py
|
||||
- backend/storage/webdav_backend.py
|
||||
- backend/tests/test_cloud_mutations.py
|
||||
- backend/tests/test_cloud_backends.py
|
||||
- backend/tests/test_cloud_provider_contract.py
|
||||
autonomous: true
|
||||
requirements:
|
||||
- CLOUD-03
|
||||
must_haves:
|
||||
truths:
|
||||
- "Cloud upload uses typed conflict and error bodies instead of hidden overwrite semantics."
|
||||
- "Provider upload differences stay behind the mutable adapter and service contract."
|
||||
- "Refreshed provider credentials can be handed upward during upload work without provider-owned database writes."
|
||||
artifacts:
|
||||
- path: "backend/api/cloud/operations.py"
|
||||
provides: "Connection-ID upload endpoint with typed conflict and retry result bodies."
|
||||
- path: "backend/services/cloud_operations.py"
|
||||
provides: "Upload dispatch that normalizes keep-both, replace, retryable error, and unsupported-replace outcomes."
|
||||
key_links:
|
||||
- from: "provider upload result"
|
||||
to: "shared queue resume decisions"
|
||||
via: "typed kind/reason response bodies"
|
||||
pattern: "conflict"
|
||||
- from: "refreshed provider credentials"
|
||||
to: "service-layer persistence handoff"
|
||||
via: "upload success and retry paths"
|
||||
pattern: "credentials"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Implement the bounded backend upload mechanics slice of Phase 13: connection-ID upload routing, typed conflict and retry bodies, provider-normalized keep-both or replace handling, and refreshed-credential handoff without yet folding in reconcile or audit follow-through.
|
||||
|
||||
Purpose: Finish the provider and route mechanics the shared upload queue needs before the authoritative success path is layered on top.
|
||||
Output: Upload-capable provider adapters, route and service dispatch, and passing backend upload mechanics suites.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@$HOME/.codex/gsd-core/workflows/execute-plan.md
|
||||
@$HOME/.codex/gsd-core/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@AGENTS.md
|
||||
@.planning/phases/13-virtual-local-cloud-operations/13-CONTEXT.md
|
||||
@.planning/phases/13-virtual-local-cloud-operations/13-RESEARCH.md
|
||||
@.planning/phases/13-virtual-local-cloud-operations/13-PATTERNS.md
|
||||
@backend/api/cloud/operations.py
|
||||
@backend/services/cloud_operations.py
|
||||
@backend/storage/google_drive_backend.py
|
||||
@backend/storage/onedrive_backend.py
|
||||
@backend/storage/webdav_backend.py
|
||||
</context>
|
||||
|
||||
## Artifacts this phase produces
|
||||
|
||||
- Upload support in `backend/api/cloud/operations.py` and `backend/services/cloud_operations.py`.
|
||||
- Provider-normalized keep-both, replace, retry, skip, and unsupported-replace semantics across Google Drive, OneDrive, Nextcloud-via-WebDAV, and generic WebDAV.
|
||||
- Passing upload and provider-contract suites for the mechanics half of `CLOUD-03`.
|
||||
|
||||
## Pattern analogs
|
||||
|
||||
- `backend/api/documents/upload.py` — multipart upload proxy pattern.
|
||||
- `backend/tests/test_cloud_backends.py` and `backend/tests/test_cloud_provider_contract.py` — four-provider normalization assertions.
|
||||
- `backend/services/cloud_operations.py` from 13-03 — refreshed-credential handoff and typed domain-result pattern.
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: Implement provider-normalized upload conflict semantics across the adapter boundary</name>
|
||||
<files>backend/storage/google_drive_backend.py, backend/storage/onedrive_backend.py, backend/storage/webdav_backend.py, backend/tests/test_cloud_backends.py, backend/tests/test_cloud_provider_contract.py</files>
|
||||
<read_first>
|
||||
- backend/storage/google_drive_backend.py
|
||||
- backend/storage/onedrive_backend.py
|
||||
- backend/storage/webdav_backend.py
|
||||
- backend/tests/test_cloud_backends.py
|
||||
- backend/tests/test_cloud_provider_contract.py
|
||||
- .planning/phases/13-virtual-local-cloud-operations/13-CONTEXT.md
|
||||
</read_first>
|
||||
<behavior>
|
||||
- Test 1: upload can return success, typed conflict, typed retryable error, or explicit unsupported-replace results
|
||||
- Test 2: keep-both naming is authoritative and inserts the counter before the file extension
|
||||
- Test 3: provider-specific conflict semantics normalize into one shared contract across all four providers
|
||||
</behavior>
|
||||
<action>
|
||||
Implement D-03 and D-04 inside the provider layer so Google Drive, OneDrive, and the shared WebDAV path normalize upload conflicts, replace support, keep-both suffixing, and retryable transient failures into one mutable-operation contract. Preserve broader Google Drive access assumptions, OneDrive refreshed-credential handoff, and SSRF validation on every WebDAV upload request. Keep Nextcloud on the shared WebDAV mutation path unless a narrow override is strictly required.
|
||||
</action>
|
||||
<acceptance_criteria>
|
||||
- upload provider suites pass for all four supported providers
|
||||
- keep-both naming is authoritative and consistent across providers
|
||||
- provider code returns typed results and never writes `cloud_items`, audit rows, or router-visible provider payloads directly
|
||||
</acceptance_criteria>
|
||||
<verify>
|
||||
<automated>docker compose run --rm backend pytest -v tests/test_cloud_backends.py tests/test_cloud_provider_contract.py -k "upload or replace or conflict" -x</automated>
|
||||
</verify>
|
||||
<done>The adapter layer now exposes typed, provider-normalized upload mechanics for the shared queue.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 2: Expose connection-ID upload dispatch with typed route and service results</name>
|
||||
<files>backend/api/cloud/operations.py, backend/api/cloud/schemas.py, backend/services/cloud_operations.py, backend/tests/test_cloud_mutations.py</files>
|
||||
<read_first>
|
||||
- backend/api/cloud/operations.py
|
||||
- backend/api/cloud/schemas.py
|
||||
- backend/services/cloud_operations.py
|
||||
- backend/tests/test_cloud_mutations.py
|
||||
- .planning/phases/13-virtual-local-cloud-operations/13-CONTEXT.md
|
||||
</read_first>
|
||||
<behavior>
|
||||
- Test 1: the upload route returns typed success, conflict, retryable error, and unsupported-replace bodies
|
||||
- Test 2: the service layer owns refreshed-credential persistence handoff above the provider boundary
|
||||
- Test 3: queue-control semantics come from backend-authored results instead of Vue-side inference
|
||||
</behavior>
|
||||
<action>
|
||||
Wire the connection-ID upload endpoint through `backend/services/cloud_operations.py` and `backend/api/cloud/schemas.py` so the route returns stable `kind` and `reason` bodies for Keep both, Replace, Skip, Retry, Cancel all, or unsupported-replace outcomes. Keep this plan bounded to mechanics: normalize provider results, surface refreshed credentials upward for encrypted persistence, and leave centralized reconciliation plus metadata-only audit follow-through to the next plan.
|
||||
</action>
|
||||
<acceptance_criteria>
|
||||
- upload route and mutation suites pass for typed mechanics and credential-safe results
|
||||
- queue-control semantics are backend-authored and credential-safe
|
||||
- this plan does not yet add upload-specific reconciliation or success-audit behavior outside the existing foundations
|
||||
</acceptance_criteria>
|
||||
<verify>
|
||||
<automated>docker compose run --rm backend pytest -v tests/test_cloud_mutations.py tests/test_cloud_backends.py tests/test_cloud_provider_contract.py -k "upload or replace or conflict" -x</automated>
|
||||
</verify>
|
||||
<done>The backend now exposes the bounded upload mechanics the next follow-through plan can finish.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| browser upload → provider write | User content enters a provider-owned mutation path through DocuVault authorization only. |
|
||||
| provider SDK/HTTP → route result | Provider conflict, retry, and replace behavior must be normalized before Vue consumes it. |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-13-16 | T | upload conflict handling | mitigate | Typed upload result bodies and provider-contract tests forbid silent overwrite behavior. |
|
||||
| T-13-17 | I | route result typing | mitigate | Upload route tests verify no provider URLs, tokens, or raw payloads escape typed responses. |
|
||||
| T-13-18 | T | provider boundary | mitigate | WebDAV SSRF and OneDrive refresh handoff remain covered by provider suites. |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- Pass the bounded backend upload and provider-contract suites.
|
||||
- Confirm all backend pytest invocations are direct containerized commands.
|
||||
- Confirm upload mechanics stop at typed route and service results, leaving reconcile and audit follow-through to the next plan.
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- The backend can upload into the current cloud folder with typed conflict and retry semantics.
|
||||
- Provider-specific differences remain behind the shared contract and service layer.
|
||||
- The upload mechanics plan stays within 9 files and leaves reconcile plus audit follow-through for the next bounded plan.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/13-virtual-local-cloud-operations/13-05-SUMMARY.md` when done
|
||||
</output>
|
||||
Reference in New Issue
Block a user