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,172 @@
|
||||
---
|
||||
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>
|
||||
Reference in New Issue
Block a user