Files
curo1305andClaude Sonnet 4.6 b67e77dd69 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>
2026-06-23 20:34:57 +02:00

173 lines
8.7 KiB
Markdown

---
phase: "13"
plan: "08"
type: execute
wave: 5
depends_on:
- "13-03"
- "13-04"
- "13-06"
files_modified:
- backend/api/cloud/operations.py
- backend/api/cloud/schemas.py
- backend/services/cloud_operations.py
- backend/services/cloud_items.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-04
- CLOUD-05
- CLOUD-09
must_haves:
truths:
- "Create-folder and rename collisions auto-suffix human-readable counters with bounded retry."
- "Stale create or rename targets stop, refresh the affected folder, and return typed retry guidance instead of forcing the mutation."
- "Successful create and rename operations preserve stable cloud item identity through centralized reconciliation."
artifacts:
- path: "backend/api/cloud/operations.py"
provides: "Create-folder and rename endpoints with typed collision and stale-result bodies."
- path: "backend/services/cloud_operations.py"
provides: "Create-folder and rename orchestration with bounded retry and reconcile-on-success behavior."
key_links:
- from: "create-folder and rename provider result"
to: "cloud_items stable row identity"
via: "centralized post-mutation reconciliation"
pattern: "parent_ref"
---
<objective>
Implement the bounded backend create-folder and rename slice of Phase 13: collision-safe naming, stale guards, bounded retry, and stable-identity reconciliation for successful results.
Purpose: Deliver `CLOUD-04` and `CLOUD-05` without mixing move or delete semantics into the same plan.
Output: Passing backend create-folder and rename mutation suites with centralized reconciliation intact.
</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
@backend/api/cloud/operations.py
@backend/services/cloud_operations.py
@backend/services/cloud_items.py
@backend/storage/google_drive_backend.py
@backend/storage/onedrive_backend.py
@backend/storage/webdav_backend.py
</context>
## Artifacts this phase produces
- Create-folder and rename support in the operations router and cloud operations service.
- Four-provider collision, bounded-retry, and stale-result normalization through Google Drive, OneDrive, Nextcloud-via-WebDAV, and generic WebDAV.
- Passing create-folder and rename backend, provider-contract, and mutation suites.
## Pattern analogs
- `backend/api/folders.py` — local create and rename handler structure.
- `backend/services/cloud_items.py` — stable identity and freshness reconciliation behavior.
- `backend/tests/test_cloud_backends.py` and `backend/tests/test_cloud_provider_contract.py` — provider normalization assertions.
<tasks>
<task type="auto" tdd="true">
<name>Task 1: Implement create-folder and rename semantics with bounded collision retries and stale guards</name>
<files>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</files>
<read_first>
- backend/api/folders.py
- backend/storage/google_drive_backend.py
- backend/storage/onedrive_backend.py
- backend/storage/webdav_backend.py
- backend/tests/test_cloud_mutations.py
- .planning/phases/13-virtual-local-cloud-operations/13-CONTEXT.md
</read_first>
<behavior>
- Test 1: create-folder and rename choose `Name (n)` counters and retry within a bounded window after concurrent collisions
- Test 2: stale version or etag mismatches stop the mutation, refresh the folder, and return a typed retry-needed result
- Test 3: provider differences normalize behind one shared contract
</behavior>
<action>
Implement D-05 through D-07 for create-folder and rename. Use the shared mutable-operation contract to normalize collision detection, bounded retry, and stale precondition failure behavior across Google Drive, OneDrive, and the shared WebDAV path. Keep counter insertion human-readable and before the file extension for files, and keep Nextcloud on the shared WebDAV mutation path unless a narrow override is unavoidable.
</action>
<acceptance_criteria>
- create-folder and rename suites pass across provider-contract and backend mutation coverage
- stale mismatches return typed retry-needed results after refresh rather than forcing the mutation
- no provider writes `cloud_items` directly or bypasses the shared contract
</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 "create or rename or stale" -x</automated>
</verify>
<done>Create-folder and rename now satisfy the bounded collision and stale-safety rules.</done>
</task>
<task type="auto" tdd="true">
<name>Task 2: Reconcile successful create-folder and rename results through stable item identity</name>
<files>backend/services/cloud_operations.py, backend/services/cloud_items.py, backend/tests/test_cloud_mutations.py</files>
<read_first>
- backend/services/cloud_operations.py
- backend/services/cloud_items.py
- backend/tests/test_cloud_mutations.py
- .planning/phases/13-virtual-local-cloud-operations/13-CONTEXT.md
</read_first>
<behavior>
- Test 1: successful create-folder and rename update navigation through centralized reconciliation before success returns
- Test 2: stable cloud item identity is preserved instead of creating duplicate rows
- Test 3: refresh guidance remains typed and tied to the service layer rather than provider-specific router branches
</behavior>
<action>
Route successful create-folder and rename results back through `backend/services/cloud_items.py` so stable row identity, parent relationships, and folder freshness stay authoritative before the API returns success. Keep the route layer thin, keep typed stale-retry guidance service-owned, and do not introduce a second reconciliation path for create or rename.
</action>
<acceptance_criteria>
- create-folder and rename mutation suites pass with reconcile-before-return behavior
- stable row identity is preserved across successful create-folder and rename operations
- centralized reconciliation remains the only metadata write path
</acceptance_criteria>
<verify>
<automated>docker compose run --rm backend pytest -v tests/test_cloud_mutations.py -k "create or rename" -x</automated>
</verify>
<done>Create-folder and rename success now satisfy the stable-identity half of `CLOUD-09`.</done>
</task>
</tasks>
<threat_model>
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| proposed new name → provider mutation | User-supplied names must be collision-safe, stale-safe, and provider-neutral before mutation. |
| mutation success → metadata state | Only authoritative success may update cloud metadata and folder freshness. |
## STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-13-24 | T | collision handling | mitigate | Mutation and provider-contract suites require bounded retry and forbid silent overwrite behavior. |
| T-13-25 | T | stale mutation safety | mitigate | Stale guards refresh and require retry instead of forcing create-folder or rename. |
| T-13-26 | T | identity reconciliation | mitigate | Successful create-folder and rename must flow back through `cloud_items.py` to preserve stable row identity. |
</threat_model>
<verification>
- Pass the create-folder and rename backend and provider-contract suites.
- Confirm every backend pytest invocation is a direct `docker compose run --rm backend pytest ...` command.
- Confirm create-folder and rename remain separated from move and delete work in both files touched and task scope.
</verification>
<success_criteria>
- The backend fully supports `CLOUD-04` and `CLOUD-05` with bounded collision and stale-safety semantics.
- Successful create-folder and rename results refresh navigation through centralized reconciliation.
- This bounded plan stays at 10 files and does not absorb move or delete behavior.
</success_criteria>
<output>
Create `.planning/phases/13-virtual-local-cloud-operations/13-08-SUMMARY.md` when done
</output>