Skip to content

[WIP] Cloud drives MVP - OneDrive vertical slice (BYO)#3064

Draft
slvnlrt wants to merge 18 commits into
spacedriveapp:mainfrom
slvnlrt:feature/cloud-drives-investigation
Draft

[WIP] Cloud drives MVP - OneDrive vertical slice (BYO)#3064
slvnlrt wants to merge 18 commits into
spacedriveapp:mainfrom
slvnlrt:feature/cloud-drives-investigation

Conversation

@slvnlrt

@slvnlrt slvnlrt commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

Cloud drives MVP — OneDrive vertical slice (BYO)

⚠️ DRAFT / WORK IN PROGRESS — DO NOT MERGE

Opened in Draft for early visibility. Implementation is complete and locally green (404 lib tests + 3 E2E tests, clippy clean, fmt clean), but manual end-to-end testing hasn't started yet and the .investigations/cloud-drives/ artefacts still need pruning before ready-for-review.

Remaining before ready-for-review:

  1. Full manual OneDrive journey against a live Azure AD app (see How to test manually) with any bug fixes it surfaces.
  2. Pruning of .investigations/cloud-drives/ — policy open for discussion (question 1 below).
  3. Applying the task-tracker updates proposed in .investigations/cloud-drives/*-proposal.md (question 2).
  4. Any feedback from this draft review.

Feedback on direction and scope is welcome now. Line-by-line review is more efficient once the draft is converted.

Summary

First end-to-end cloud drive integration on the daemon: a user can register a OneDrive (personal) account through a browser OAuth flow, list, copy and create folders on it through the normal file pipeline, and pick up remote changes via the Microsoft Graph Delta API on the next index pass. BYO Azure AD — no Spacedrive-owned provider credentials shipped, no founder action required to merge.

Google Drive and Dropbox keep their paste-tokens flow with a "browser sign-in coming soon" banner; their providers plug into the same infrastructure in a later PR (CLOUD-004).

Seventeen commits on top of fb5d4d7e7. 404 lib tests + 3 E2E tests passing, zero panics.

Context

The cloud-drive subsystem was investigated before any code was written. Reports in .investigations/cloud-drives/ established that cloud drives were ~55 % functional scaffolding with five critical blockers: two daemon-crashing panic!s, no OAuth flow, lost B2/Wasabi/Spaces rehydration on restart, disconnected create_folder for cloud, and rehashed-on-every-pass indexing.

Key reading:

What ships

User-visible

  1. One-click OneDrive sign-in. Paste client_id + client_secret obtained via the in-app Azure AD tutorial (seven steps, five redirect URIs to copy at once), click Connect with Microsoft, approve in the default browser, the daemon picks up the redirect on a loopback port, stores tokens encrypted, and the volume appears.
  2. Real file operations on cloud volumes. Local → OneDrive, OneDrive → local, OneDrive → OneDrive (server-side when the provider supports it, streaming fallback otherwise), and OneDrive → different cloud account all work through FileCopyJob. Folder creation works.
  3. Change detection on subsequent index passes. First pass seeds a Delta token; later passes call /me/drive/root/delta and advance the cursor. Throttled (429 / Retry-After respected), resilient to token invalidation (410 resyncRequired triggers a clean resync).
  4. Disconnect from the sidebar. Right-click a cloud volume → Disconnect runs volumes.remove_cloud, wiping credentials and the volume row.
  5. Fewer nonsensical menu items. Speed Test and Eject hidden on cloud volumes.
  6. Consistent icons. Renaming a OneDrive volume no longer swaps its icon for a generic disk (the duplicate substring-matching getVolumeIcon in DevicePanel.tsx was the culprit; only the scheme-based canonical version in packages/ts-client/src/volumeIcons.ts survives).

Developer-visible

  1. Provider-agnostic OAuth 2.0 + PKCE infrastructure under core/src/ops/cloud/oauth/. New providers plug in by implementing OauthProvider and registering at startup; the UI hits the same three wire methods (cloud.oauth.start, cloud.oauth.poll, cloud.oauth.cancel). No changes to CloudStorageConfig variants — the browser flow populates the existing fields on the existing VolumeAddCloudAction.
  2. BackendFeatures metadata layer at core/src/volume/backend/mod.rs. Every backend advertises server-side copy/rename, stable-file-id guarantees, change-notification kind, content-hash algorithms, case sensitivity, duplicate tolerance, max file size, and multipart threshold. Enables capability-driven code paths rather than per-provider branches.
  3. CloudCopyStrategy extending the existing strategy pattern. Four shapes (local↔cloud, cloud↔local, same-backend cloud↔cloud, cross-backend cloud↔cloud) with 8 MiB chunked streaming, 4-way writer concurrency, and progress reporting.
  4. ChangeDetector trait + OneDriveChangeDetector so future providers slot in without touching the indexer.
  5. OpenDAL 0.55 (from 0.54) with a standard layer stack — TracingLayer, ConcurrentLimitLayer(16), TimeoutLayer(30s/30s), RetryLayer(3, jitter) — wrapping every cloud operator.
  6. OAuth-refresh background task and Delta cursor persistence (cloud_sync_state table). Encrypted credential storage via SeaORM + XChaCha20-Poly1305 already existed.
  7. 17 new unit tests + 3 E2E tests via wiremock, all deterministic.

Scope boundaries

  • Provider: OneDrive personal (tenant=common) only. Google Drive and Dropbox keep paste-tokens with a "coming soon" banner. Microsoft Business / SharePoint needs a tenant-specific issuer; stubbed as TODO.
  • Client credentials: BYO. Users register their own Azure AD app. Every CloudStorageConfig::* variant already expected client_id + client_secret; validation was in place. Swapping to Spacedrive-owned credentials later is a ~5-line UI diff; the server side is forward-compatible.
  • E2E test: the OAuth journey is fully OneDrive-shaped, but the post-auth VolumeAddCloudAction step uses S3 because opendal 0.55 hardcodes graph.microsoft.com for OneDrive data-plane calls and cannot be wiremocked. OneDrive file I/O is covered at unit level against services::Memory.
  • Documentation: docs/core/cloud-integration.mdx is the target-state vision and stays unchanged. A current-state snapshot lives at .investigations/cloud-drives/cloud-integration-current-state.mdx for PR review.

Known tech debt

Every item has a TODO(cloud-mvp): ... comment at its call site referencing the plan doc.

  1. Hot-swap OAuth access token during a running pass. Refresh task rewrites cloud_credentials but CloudBackend reads tokens at construction; long-running indexing passes won't pick up rotation mid-flight. TODOs at core/src/ops/cloud/change_detection/onedrive.rs:51 and core/src/ops/indexing/phases/processing.rs:83.
  2. Consume the delta stream to skip re-hashing unchanged files. Delta cursor advances, but the main indexing loop still re-hashes every entry each pass. Needs OpenDAL to surface provider_file_id on listing (it doesn't today) or a cross-reference layer. Machinery is in place.
  3. Rename detection emits Modified. ChangeKind::Renamed { from_path } exists but the OneDrive detector never constructs it — a single Graph delta response doesn't carry the previous path. Needs a per-provider_file_id path cache. The indexer still reconciles renames via stable id.
  4. ETag / content_md5 checksum verification on cloud paths (TODO at core/src/ops/files/copy/strategy.rs:844). Currently warns and proceeds; integrity guaranteed by OpenDAL's chunked writer.
  5. Backblaze B2, Wasabi, DigitalOcean Spaces silently dropped at daemon restart — pre-existing catch-all at core/src/volume/manager.rs:335-338. Not fixed in this PR; constructors exist for S3, GoogleDrive, OneDrive, Dropbox, AzureBlob, GCS.
  6. Google Drive + Dropbox browser OAuth. Infrastructure ready; only concrete providers and UI forms missing. Tracked outside CLOUD-004.
  7. Reconnect UI when a refresh token expires (users currently delete and re-add).
  8. Windows case-insensitive FS detection on LocalBackend.
  9. Copy-on-write detection on btrfs / apfs for LocalBackend::server_side_copy.

How to test manually

Prerequisites

  1. Azure AD app registration (one-time, ~5 minutes):
    • Sign in to https://portal.azure.com.
    • App registrations → New registration. Name anything, supported accounts = Personal Microsoft accounts only.
    • Redirect URI: add all five of http://127.0.0.1:53682, :53683, :53684, :53685, :53686 as Web (not SPA).
    • Authentication → Advanced → Allow public client flows = Yes.
    • API permissions → Microsoft Graph → Delegated → Files.ReadWrite.All, offline_access, User.Read. Grant admin consent.
    • Certificates & secrets → New client secret → copy the Value.
    • Overview → copy the Application (client) ID.
  2. A folder on OneDrive with mixed files (a PDF, a few images, a nested sub-folder).

Test sequence

  1. Build: cargo build (or cargo run --bin sd-cli -- restart if a daemon is already running).
  2. Launch Tauri: cd apps/tauri && bun run tauri:dev.
  3. Add storage → Cloud → OneDrive → expand the tutorial once to verify it renders, then paste client ID and client secret.
  4. Click Connect with Microsoft. The default browser should open Microsoft's login page pre-filled. Approve.
  5. The modal should close and the volume should appear in the sidebar within 2 seconds, labelled with your Microsoft display name.
  6. Click the OneDrive volume, browse the root. Files and folders should list.
  7. Right-click a local file → Copy to… → OneDrive volume → destination folder. Watch progress.
  8. Verify on https://onedrive.live.com that the file uploaded.
  9. Right-click a OneDrive file → Copy to… → local destination. Verify bytes match (shasum).
  10. Right-click a OneDrive folder → New folder. Verify on https://onedrive.live.com.
  11. Delete a file on https://onedrive.live.com, trigger a re-index in the app, confirm it disappears from the view.
  12. Right-click the OneDrive volume → Disconnect. Volume disappears, cloud_credentials row removed.
  13. Add the same volume again with the same credentials — Microsoft remembers, tokens refresh.

Failure-mode checks

  • Start a Connect flow, close the browser tab, click Cancel sign-in in the app. Modal should return to initial state, no volume added.
  • Close the modal entirely during awaiting-browser. No ghost loopback server should remain (check netstat -an | findstr 5368 returns nothing within ~10 s).
  • Tamper with a cloud_credentials row (garbage refresh_token), restart the daemon. Refresh task should log an auth failure and not crash.

How to review

Commit narrative order

fe5a5331d  investigation reports + MVP plan
dcb925162  foundation (OpenDAL 0.55, layers, BackendFeatures)
03483252f  file copy / move / create_folder
22aaf310b  correction of Set 2 task tracking
391e963e3  OAuth infrastructure (BYO, loopback + PKCE)
67c3e179a  wire / TS shape fix
2e8f048dc  .tasks/ pristine
3f1fd13d1  orchestration playbook
1461281ee  OneDrive OAuth provider
7f684ee53  OneDrive browser connect form
3406a9d8b  OneDrive Delta API change detection
c81777598  annex UI fixes
232e125c4  CloudCopyStrategy wiring
9482354cd  E2E test + docs + CLOUD-004 proposal
18cad0691  OpenDAL 0.55 token-constraint fix
0a2db20b9  restore target-state docs
f6234dee1  comment audit and trim

Each commit builds, tests and lints cleanly on its own.

Reading paths by concern

  • OAuth subsystem: core/src/ops/cloud/oauth/ (start, poll, cancel, complete, provider trait, loopback, flow store, refresh, providers/onedrive).
  • Change detection: core/src/ops/cloud/change_detection/ (types, detector trait, OneDrive impl, repository, delta pass).
  • Copy strategy: core/src/ops/files/copy/strategy.rs + routing.rs.
  • UI: packages/interface/src/routes/explorer/components/OneDriveConnectForm.tsx + AddStorageModal.tsx.
  • Migrations: core/src/infra/db/migration/m20260418_000001_*.rs and m20260418_000002_*.rs.
  • E2E: core/tests/onedrive_end_to_end_test.rs.

Risk and rollback

  • The daemon does not crash on any cloud path — every branch returns a typed Result.
  • Users with OneDrive volumes see their file I/O return errors; existing local volumes are unaffected.
  • Rollback is a clean git revert f6234dee1..fe5a5331d^. No data-loss migrations; cloud_sync_state and the provider_file_id column on entries are purely additive.
  • Non-cloud users see no behavioural change. The OpenDAL 0.55 bump and layer stack hit the cloud operator path only; LocalBackend was updated for BackendFeatures parity but its behaviour is identical.

Dependency additions

  • opendal 0.54 → 0.55 (already a direct dep)
  • oauth2 = "5"
  • webbrowser = "1"
  • dashmap = "6"
  • subtle = "2" (constant-time CSRF)
  • base64 = "0.22"
  • wiremock = "0.6" (dev-dep only)

All MIT/Apache-2.0.

Questions for reviewers

  1. .investigations/ policy. Keep it in the tree, or drop before merge? Options: (a) keep as project memory; (b) move to an external design repo; (c) keep only the plan and proposals, drop the state-of-art reports.
  2. Task tracker updates. Four update proposals sit in .investigations/cloud-drives/*-proposal.md. Applied as a follow-up commit on this branch, or a separate maintainer PR?
  3. Google Drive / Dropbox browser flows. In this PR (~1500 LOC each), or a separate PR once OneDrive is confirmed stable?
  4. BYO client_id long-term. If you'd rather ship an official Spacedrive Azure AD app, it's a small UI change and two constants — no backend work.

slvnlrt added 17 commits April 18, 2026 11:14
Full audit of cloud drive state (backend, frontend, git history, maturity) and research on OAuth native apps, OpenDAL 0.55, change detection, and reference implementations (rclone, object_store, Nextcloud, Syncthing, Cyberduck, Kopia).

Contains the 8 commit-set operational plan for the OneDrive vertical slice MVP with BYO client_id architecture.

No code changes; baseline for the MVP implementation that follows.
Upgrades OpenDAL to 0.55 and adapts the two jiff::Timestamp call sites.

Wraps every CloudBackend operator with a retry+timeout+concurrent-limit+tracing layer stack to gain resilience, logging, and protection against rate limits.

Introduces BackendFeatures (server_side_copy, stable_file_id, change_notifications, content_hash, case_insensitive, supports_duplicates, max_file_size, multipart_threshold) per backend, consumed by later work in file ops and indexing.

Enriches BackendMetadata with etag/version/content_md5/provider_file_id so the indexer can short-circuit rehashing when providers expose content hashes.

Fixes CloudBackend::exists swallowing authentication errors as "not found", a silent data-integrity hazard.

Part of the OneDrive MVP vertical slice. See .investigations/cloud-drives/06-mvp-onedrive-vertical-slice.md#set-1.
Replaces the two FileCopyJob panic sites with a branch that uses server-side copy when both endpoints are the same cloud backend with server_side_copy capability, and stream-copies through 8 MiB chunked writers with concurrency 4 otherwise.

Wires CreateFolderAction to the existing CloudBackend::create_directory instead of returning an Internal error.

Adds CloudBackend::copy as the public entry point guarded by BackendFeatures::server_side_copy, so callers short-circuit with a typed error rather than discovering limitations deep inside OpenDAL.

Closes FILE-003. Part of the OneDrive MVP vertical slice. See .investigations/cloud-drives/06-mvp-onedrive-vertical-slice.md#set-2.
Set 2 added the CloudBackend::copy primitive, wired CreateFolderAction to cloud, and made FileCopyJob::new_rename/MoveJob::rename total for SdPath::Cloud (eliminating two daemon panics). It did not add a CloudCopyStrategy or router integration, so end-to-end file copy involving cloud paths still fails with a typed error.

Reverts the over-marked acceptance criteria in FILE-003 and CLOUD-003 to unchecked and records the partial progress in a dedicated section so the tracker stays honest.
Adds a provider-agnostic OAuth 2.0 subsystem under core/src/ops/cloud/oauth with the authorization-code-plus-PKCE flow from RFC 8252 wired to a one-shot loopback HTTP server.

CloudOauthStartAction binds a loopback listener, generates a CSRF state token and a PKCE S256 challenge, returns the authorization URL for the frontend to open, and spawns a detached task that drives the flow to completion. CloudOauthPollQuery exposes the in-memory flow state machine to the UI. CloudOauthCancelAction aborts a pending flow.

A background CloudTokenRefreshTask iterates over cloud_credentials, refreshes OAuth tokens about to expire, and writes the rotated tokens back through CloudCredentialManager. The task is a no-op until Set 4 registers OneDrive in the OauthProviderRegistry.

BYO architecture preserved: client_id and client_secret are parameters on every call, never stored on the provider. CloudStorageConfig::OneDrive schema unchanged so existing volumes continue to load.

Creates CLOUD-004 to track the infrastructure separately from CLOUD-003 (volume wiring) and FILE-003 (file ops). See .investigations/cloud-drives/06-mvp-onedrive-vertical-slice.md#set-3.
Remove #[serde(flatten)] from OauthFlowStatus::Completed. specta does
not honour serde flatten attributes, so the generated TS type exposed
`tokens: TokenSet` while the runtime JSON hoisted TokenSet fields to
the top level — the frontend would fail to parse poll responses.

Keep tokens nested, matching what specta already generated. Add a
regression test asserting the exact wire shape.
The .tasks/ tree is maintained upstream by the founder as part of the
project tracker, not by feature branches. Our earlier cloud-drives
commits inadvertently edited CLOUD-003 and FILE-003 and created
CLOUD-004 in that tree. Revert CLOUD-003 and FILE-003 to the
upstream/main state and relocate CLOUD-004 to
.investigations/cloud-drives/CLOUD-004-oauth-infrastructure-proposal.md
so the tracker stays clean. Task status updates will be proposed
through the PR description for the founder to accept.
Codifies the single-agent-at-a-time discipline, the agent-prompt
template, the per-set workflow, and the concurrency incident from
2026-04-18. Future sets follow this playbook rather than ad-hoc
prompting.
Implements OauthProvider trait for OneDrive personal (tenant=common):

- PKCE S256 authorization URL with prompt=select_account

- Authorization-code and refresh-token exchange

- Refresh-token preservation when Microsoft omits it on refresh

- Graph /me displayName lookup with userPrincipalName fallback

- 5 loopback ports (53682-53686) matching Microsoft exact-match registered URIs

Registered in OauthProviderRegistry at core startup so the refresh task can rotate credentials on first tick. 10 wiremock-backed tests cover id, loopback ports, URL shape, exchange happy/invalid_grant, refresh rotation/preservation, display_name priority/fallback/HTTP-error.

Set 4 of 8 for cloud-drives MVP (OneDrive vertical slice). See .investigations/cloud-drives/06-mvp-onedrive-vertical-slice.md#set-4.
Replaces the OneDrive paste-tokens UI with a browser-driven BYO OAuth
flow so non-developers can connect their account without digging into
Microsoft Graph. Google Drive and Dropbox keep the paste-tokens UX and
gain a "Browser sign-in coming soon" banner pointing at the future
generalisation.

Created:
  packages/interface/src/routes/explorer/components/OneDriveConnectForm.tsx

  - 613 LOC self-contained React component.
  - Orchestrates cloud.oauth.start -> platform.openLink -> cloud.oauth.poll
    (refetchInterval 1s) -> volumes.add_cloud, reusing the parent's
    useForm + onSubmitCloud handler so volume creation stays DRY.
  - Collapsible 7-step Azure AD tutorial with placeholder screenshot
    blocks (real PNGs can be dropped in later without code changes).
  - "Open Azure Portal" and "Copy redirect URIs" helpers pre-fill the
    five Microsoft-registered loopback URIs (53682-53686).
  - UUID v4 validation on client_id, password Input for client_secret.
  - Cancel button + unmount cleanup call cloud.oauth.cancel so the
    daemon does not hold the loopback port for the full 5-min TTL.
  - Semantic Tailwind classes only, no var() / hex / inline <style>,
    no any / as any. Types from @sd/ts-client.

Modified:
  packages/interface/src/routes/explorer/components/AddStorageModal.tsx

  - Split isOAuthType into isOneDrive + isLegacyOAuthType.
  - OneDrive branch early-returns with the new form mounted inside
    StorageDialog, hiding default buttons and keeping Back.
  - Legacy branch (gdrive, dropbox) gains the "coming soon" banner
    and a TODO(cloud-mvp) cross-referencing section 9 of the MVP plan.

TypeScript: no new errors on changed files; pre-existing unrelated
ambient-declaration errors for @sd/assets PNG imports remain.

Refs: .investigations/cloud-drives/06-mvp-onedrive-vertical-slice.md
Introduces the foundation for incremental cloud indexing via Microsoft Graph's /me/drive/root/delta endpoint. Adds a cloud_sync_state table and a provider_file_id column on entries, a provider-agnostic ChangeDetector trait, the OneDriveChangeDetector implementation with 410/429/401 handling, a CloudSyncStateRepository, and a delta-pass orchestrator that runs as a pre-pass in the processing phase to advance the delta cursor. Full re-hash skipping is deferred (would require OpenDAL listing changes beyond this set's scope); the machinery is in place for a follow-up commit to consume the change stream.
- Cloud volumes get a 'Disconnect' context menu item (purges credentials via volumes.remove_cloud); Speed Test and Eject are hidden for them.

- Remove the broken GroupType::Cloud option from AddGroupModal and SpaceCustomizationPanel dropdowns (no CloudGroup renderer yet). Keep the Rust variant so existing library JSON rows still deserialize; added TODO(cloud-mvp) doc-comment in core/src/domain/space.rs.

- Unify getVolumeIcon: delete the name-substring duplicate in DevicePanel.tsx and redirect VolumeBar.tsx to the canonical scheme-based helper in packages/ts-client. Widen its param so callers no longer need 'as any'.

- Add 9 bun tests asserting a renamed cloud volume still maps to its provider icon.
Local and cloud volumes can now be mixed in FileCopyJob without the strategy layer rejecting cloud paths as non-local. CloudCopyStrategy handles the four transfer shapes: local upload, cloud download, same-backend server-side copy (falling back to client-side streaming when the provider capability is disabled), and cross-backend streaming. The router intercepts cloud endpoints before the device-slug branch so they stop falling through to LocalStreamCopyStrategy.

12 new tests cover each shape plus routing selection, progress callback cadence, and the cloud_key trim helper. Checksum verification on cloud paths is stubbed with a warn! and a TODO pointing to set-8b for ETag/content_md5 wiring.
Integration test onedrive_end_to_end_test covers the OAuth journey end-to-end against wiremocked Microsoft endpoints: start flow, simulate loopback redirect, poll until Completed, tokens extracted, volume registered, then torn down. Two adjacent tests pin the cancel path and the token-exchange failure path. Unit coverage (10 tests in change_detection/onedrive.rs, 10 in providers/onedrive.rs, 12 in copy strategy) covers the HTTP surface the integration test cannot touch without promoting private constructors.

docs/core/cloud-integration.mdx rewritten against reality: removes false claims (40+ providers, OS keyring, cross-cloud moves, thumbnails, cost tracking), adds honest supported-services matrix, BYO Azure AD setup, security model, change detection wiring, and known limitations. From 381 lines of marketing to 178 lines of fact.

CLOUD-004 proposal in .investigations/ finalised with accurate delivery status. Sibling CLOUD-003 and FILE-003 update proposals list which acceptance criteria the MVP has closed so the founder can copy them into the upstream tracker. MVP-CHANGELOG.md captures the full OneDrive vertical slice for the PR description.

E2E test surfaced a pre-existing VolumeAddCloudAction issue: the OneDrive branch forwards both access_token and refresh_token to OpenDAL 0.55's Onedrive builder, which rejects that combination. The test therefore completes the OAuth journey in OneDrive shape but registers the resulting volume as S3 to exercise the rest of the action handler. Fix is out of scope here and tracked for a follow-up commit.
OpenDAL's Onedrive and Gdrive builders treat access_token and (refresh_token + client_id + client_secret) as mutually exclusive configurations; passing both fails the builder with a config validation error. CloudBackend::new_onedrive and new_google_drive were forwarding every field from CloudStorageConfig, which prevented either provider from constructing once a refresh_token was present (always, after the OAuth flow). Switch both to the long-lived refresh path so OpenDAL rotates access tokens internally. Argument stays in the signature for caller stability.

Surfaced by the Set 8b integration test. Dropbox was already using refresh-only, so no change there. Documented in docs/core/cloud-integration.mdx known limitations is now unnecessary for this case since the constraint is handled.
… to investigations

docs/core/cloud-integration.mdx describes the aspirational vision (target state) and should not be rewritten to match current reality — that conflates the upstream specification with MVP progress. Restored to upstream. The factual rewrite lands at .investigations/cloud-drives/cloud-integration-current-state.mdx with a note cross-referencing the target doc, so the PR makes the vision-vs-reality gap explicit without overwriting the specification.
Sweep across the 12 files produced or extensively modified by Sets 1-8
to remove comments that paraphrased visible code, restated field or
variant names, or included verbose factory/JSDoc blocks. Keeps every
WHY-focused justification, every error-handling strategy note, every
platform-specific caveat, and every TODO(cloud-mvp) cross-reference
into the plan doc.

Net -145 LOC (113+/258-). Tests still 404 passing, clippy clean, no
logic changes.
@coderabbitai

coderabbitai Bot commented Apr 19, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 37597c24-6ba3-4fb6-8ce0-d71a987d532f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@slvnlrt slvnlrt force-pushed the feature/cloud-drives-investigation branch from 2473222 to 5c44106 Compare April 19, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant