Skip to content

feat: per-source toggle to back up OneDrive cloud-only placeholder files - #133

Merged
pmaxhogan merged 1 commit into
mainfrom
feat/onedrive-placeholder-toggle
Jul 20, 2026
Merged

pmaxhogan merged 1 commit into
mainfrom
feat/onedrive-placeholder-toggle

Conversation

@pmaxhogan

@pmaxhogan pmaxhogan commented Jul 20, 2026

Copy link
Copy Markdown
Owner

What & why

Issue #4: give each backup source a policy for OneDrive / cloud-only placeholder
files. Windows OneDrive Files-On-Demand marks a dehydrated placeholder with
FILE_ATTRIBUTE_RECALL_ON_OPEN; opening it forces a network hydration, so the
scanner has always skipped these by default (DESIGN s5.2.1) to avoid silently
pulling down terabytes of cloud-only data. Some users, though, want those files
backed up. This adds a per-source opt-in to do exactly that.

Policy semantics

New PlaceholderPolicy (serde snake_case) carried end-to-end:

  • skip (default): unchanged behaviour - a cloud-only placeholder is skipped
    before stat/hash and its existing file_state row is preserved (not treated as
    a deletion).
  • force_download: the scanner does NOT skip on the recall attribute; the
    file flows through the normal open/read path and Windows hydrates it on read
    (the byte read happens downstream at hash/upload time, so scan-time stat
    never triggers hydration).

Stored as a new nullable placeholder_policy TEXT column (migration 0008).
NULL (every pre-migration row) and any unrecognised value decode to skip, so
the change is fully backward compatible with no data migration.

Shape

  • crates/driven-core: PlaceholderPolicy enum + SourceRow.placeholder_policy,
    migration 0008, 5 sqlx query sites (2 SELECT + 3 upsert) + regenerated
    committed .sqlx/. Scanner gates the skip via a pure
    should_skip_placeholder(attrs, policy) fn (mirrors the repo's
    classify_* / fallback_decision pure-decision pattern) so both branches are
    unit-testable cross-platform (the real attribute cannot be synthesised on a
    temp file portably).
  • IPC: AddSourceRequest (#[serde(default)]), SourcePatch
    (Option<PlaceholderPolicy>), and SourceDto gain the field; wired through
    add_source / update_source. TS mirrors updated in ipc/types.ts.
  • UI: a "Back up OneDrive cloud-only files" toggle with an explanatory caption in
    BOTH the add-source wizard (exclusions step) and the SourceTable inline edit
    panel; strings localized in en-US.json.

Tests

  • Rust: should_skip_placeholder both-policy unit test; from_db NULL/unknown ->
    skip + encode round-trip; sqlite placeholder_policy_round_trip (default +
    force_download persist/reload/flip). cargo fmt --check, clippy --workspace --all-targets -D warnings, cargo test -p driven-core / -p driven-app / -p driven-cli / -p driven-chaos all green. Migration 0008 verified applying
    in order.
  • UI: extended settings-components.test.ts with mount tests exercising the new
    toggle in the wizard and both SourceTable states (reflect current policy +
    patch on save). pnpm lint, vue-tsc --noEmit, pnpm test:unit all green.

Note: the scanner import of PlaceholderPolicy is #[cfg(any(windows, test))]
gated to match its only (cfg-gated) consumer, so the non-Windows CI clippy legs
stay warning-free.

Refs #34 (backlog item: OneDrive cloud-only placeholders).

🤖 Generated with Claude Code

Add a per-source PlaceholderPolicy (skip | force_download) end-to-end:
new nullable placeholder_policy column (migration 0008), PlaceholderPolicy
enum on SourceRow, scanner gate via a pure should_skip_placeholder fn,
DTO + TS mirrors, add-source wizard + SourceTable edit controls.

Closes #4.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QZQVP2tUuTLh8oL31D8heC
@github-actions

Copy link
Copy Markdown
Contributor

Coverage

Area main this PR delta
Rust (lib crates) 78.59% 78.64% +0.06 (OK)
UI (vue/ts) 88.51% 88.58% +0.07 (OK)

Gate: passed - no coverage regression (epsilon 0.1 pp).

@pmaxhogan
pmaxhogan enabled auto-merge (squash) July 20, 2026 17:01
@pmaxhogan
pmaxhogan merged commit 6863ea3 into main Jul 20, 2026
19 checks passed
@pmaxhogan
pmaxhogan deleted the feat/onedrive-placeholder-toggle branch July 20, 2026 17:02
@github-project-automation github-project-automation Bot moved this from Todo to Done in Driven Jul 20, 2026
pmaxhogan added a commit that referenced this pull request Jul 24, 2026
🤖 I have created a release *beep* *boop*
---


## [2.1.0](v2.0.1...v2.1.0)
(2026-07-24)


### Features

* **core:** adaptive upload parallelism with throughput probe and
disk-saturation gate
([#143](#143))
([8ecced6](8ecced6))
* **core:** filesystem timestamp-granularity probe with ctime fallback
and per-directory gitignore cascade
([#141](#141))
([344262c](344262c))
* **drive:** support Google Shared Drive destinations end-to-end
([#142](#142))
([d9c3161](d9c3161))
* **net:** native OS reachability backends with automatic fallback
([#138](#138))
([319e85f](319e85f))
* **net:** SOCKS5 and PAC proxy support for all outbound connections
([#145](#145))
([2f0b7d1](2f0b7d1))
* **net:** support a custom corporate root CA for all outbound
connections ([#134](#134))
([929e93d](929e93d))
* per-source toggle to back up OneDrive cloud-only placeholder files
([#133](#133))
([6863ea3](6863ea3))
* **telemetry:** capture latency percentiles and add rollup query
endpoint ([#132](#132))
([4e9fde6](4e9fde6))
* **telemetry:** preview exactly what a telemetry ping sends
([#139](#139))
([95fbd9a](95fbd9a))


### Bug Fixes

* **core:** commit file_state for a create that skipped post-upload so
the next scan updates instead of re-creating
([#146](#146))
([f5230d1](f5230d1))
* **deps:** bump tauri-winrt-notification to drop vulnerable quick-xml
(closes [#89](#89))
([#129](#129))
([232fd8f](232fd8f))
* **telemetry:** exclude pre-schema rows from latency rollup
([#137](#137))
([1ae6220](1ae6220))
* **ui:** add cursor pointer to buttons and link-buttons
([#136](#136))
([dbd4809](dbd4809))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant