Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
aa6c88d
Prepare 1.8.7 trust and portability contracts
ATAC-Helicopter Aug 11, 2026
4df3442
Service the .NET 10 runtime baseline
ATAC-Helicopter Aug 12, 2026
e14ea11
Keep release metadata on the packaged version
ATAC-Helicopter Aug 12, 2026
bff3e87
Cover the runtime security audit
ATAC-Helicopter Aug 12, 2026
e5add6d
Restrict runtime audit inputs
ATAC-Helicopter Aug 12, 2026
8aa66fe
Define the 1.8.7 trust contracts
ATAC-Helicopter Aug 12, 2026
81b3865
Establish durable installation identity
ATAC-Helicopter Aug 12, 2026
18cdd69
Add repository writer leases
ATAC-Helicopter Aug 12, 2026
089a1b4
Protect cross-machine metadata writers
ATAC-Helicopter Aug 12, 2026
b45c290
Release coordination database handles
ATAC-Helicopter Aug 12, 2026
f41e893
Clear cross-machine quality gates
ATAC-Helicopter Aug 12, 2026
a7dfbd1
Start the 1.8.7 changelog
ATAC-Helicopter Aug 12, 2026
6a5f3ab
Plan 1.8.7 codebase simplification
ATAC-Helicopter Aug 12, 2026
1cb932b
Clear metadata sync analyzer findings
ATAC-Helicopter Aug 12, 2026
96ac56a
Consolidate network mount parsing
ATAC-Helicopter Aug 12, 2026
c226e45
Share theme color primitives
ATAC-Helicopter Aug 12, 2026
87366ef
Record the first simplification pass
ATAC-Helicopter Aug 12, 2026
37e9848
Allow unreleased changelog development
ATAC-Helicopter Aug 12, 2026
b69287c
Clear follow-up Sonar findings
ATAC-Helicopter Aug 12, 2026
2e8cd7c
Decompose metadata import workflows
ATAC-Helicopter Aug 12, 2026
1e4e135
Standardize metadata import helpers
ATAC-Helicopter Aug 12, 2026
dbe70fb
Clear metadata analyzer edge cases
ATAC-Helicopter Aug 12, 2026
c08ed52
Generate canonical release manifests
ATAC-Helicopter Aug 12, 2026
6c02ad1
Harden release manifest generation
ATAC-Helicopter Aug 12, 2026
7e4cf6d
Verify updates against canonical manifests
ATAC-Helicopter Aug 12, 2026
9ffaa6d
Bound release manifest version parsing
ATAC-Helicopter Aug 12, 2026
8b30326
Ignore Blueprints local project state
ATAC-Helicopter Aug 13, 2026
e24b48a
Modernize utility window layouts
ATAC-Helicopter Aug 13, 2026
e402742
Standardize and harden backup presets
ATAC-Helicopter Aug 13, 2026
0ba5c30
Document preset safety and finish utility polish
ATAC-Helicopter Aug 13, 2026
4ce0081
Align preset safety contract and work item IDs
ATAC-Helicopter Aug 13, 2026
13ed4d2
Fix duplicate metadata preview counts
ATAC-Helicopter Aug 15, 2026
0304ff6
Update test infrastructure dependencies
ATAC-Helicopter Aug 15, 2026
064f468
Resolve Sonar findings and expand regression coverage
ATAC-Helicopter Aug 15, 2026
9349e56
Cover release manifest trust boundaries
ATAC-Helicopter Aug 15, 2026
a2690be
Limit imported snapshot tombstones to deletions
ATAC-Helicopter Aug 15, 2026
9f90a1c
Standardize destination status presentation
ATAC-Helicopter Aug 15, 2026
5b27351
Cover coordination and metadata failure boundaries
ATAC-Helicopter Aug 15, 2026
b1ce7b6
Cache verified updater manifests across restarts
ATAC-Helicopter Aug 15, 2026
221a95e
Make roadmap synchronization contract-safe
ATAC-Helicopter Aug 15, 2026
f396ee6
Harden roadmap synchronization boundaries
ATAC-Helicopter Aug 15, 2026
bde641d
Keep roadmap content out of process arguments
ATAC-Helicopter Aug 15, 2026
e86f86f
Bound disposable storage and guard managed mounts
ATAC-Helicopter Aug 15, 2026
911db42
Prune stale updater and recovery work individually
ATAC-Helicopter Aug 15, 2026
2acb090
Expose repository writer safety controls
ATAC-Helicopter Aug 16, 2026
64c001e
Set the two-week minor release cadence
ATAC-Helicopter Aug 16, 2026
173c4e9
Make cross-machine conflict decisions durable
ATAC-Helicopter Aug 16, 2026
b6dffd9
Merge cross-machine metadata changes safely
ATAC-Helicopter Aug 16, 2026
209387f
Reconcile the 1.8.7 release plan
ATAC-Helicopter Aug 16, 2026
5514185
Guard project metadata writes by revision
ATAC-Helicopter Aug 16, 2026
e7e4c8c
Export metadata merge provenance
ATAC-Helicopter Aug 16, 2026
41c59b3
Review and undo metadata merge decisions
ATAC-Helicopter Aug 16, 2026
cb750a6
Expose canonical build identity
ATAC-Helicopter Aug 16, 2026
7af506a
Generate and attest release SBOMs
ATAC-Helicopter Aug 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ jobs:
- name: Build UI generic target
run: dotnet build src/VaultSync.UI/VaultSync.UI.csproj --framework net10.0 --configuration Release --no-restore -warnaserror -p:UseSharedCompilation=false

- name: Publish and audit self-contained runtime
run: |
dotnet publish src/VaultSync.UI/VaultSync.UI.csproj --framework net10.0 --configuration Release --runtime linux-x64 --self-contained true --output "${{ runner.temp }}/runtime-audit"
python3 scripts/runtime_pack_audit.py --runtimeconfig "${{ runner.temp }}/runtime-audit/VaultSync.UI.runtimeconfig.json"

- name: Test
run: dotnet test tests/VaultSync.Core.Tests/VaultSync.Core.Tests.csproj --configuration Release --no-restore -warnaserror -p:UseSharedCompilation=false

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
set_flag workflows_changed "$(has_change '^(\.github/workflows/|\.github/dependabot\.yml$)' && echo true || echo false)"
set_flag templates_changed "$(has_change '^(\.github/ISSUE_TEMPLATE/|\.github/PULL_REQUEST_TEMPLATE\.md$)' && echo true || echo false)"
set_flag scripts_changed "$(has_change '^(scripts/|tests/scripts/)' && echo true || echo false)"
set_flag release_changed "$(has_change '^(CHANGELOG\.md|ROADMAP\.md|docs/WHATS_NEW\.md|docs/RELEASING\.md|docs/MICROSOFT_STORE|installer/|packaging/|src/VaultSync\.UI/VaultSync\.UI\.csproj|\.github/workflows/release-assets\.yml|scripts/release_readiness_gate\.ps1)' && echo true || echo false)"
set_flag release_changed "$(has_change '^(CHANGELOG\.md|ROADMAP\.md|docs/WHATS_NEW\.md|docs/RELEASING\.md|docs/MICROSOFT_STORE|docs/schemas/|installer/|packaging/|src/VaultSync\.UI/VaultSync\.UI\.csproj|\.github/workflows/release-assets\.yml|scripts/release_(manifest\.py|readiness_gate\.ps1))' && echo true || echo false)"
set_flag store_changed "$(has_change '^(packaging/VaultSync\.Store/|docs/MICROSOFT_STORE|src/VaultSync\.UI/VaultSync\.UI\.csproj)' && echo true || echo false)"

echo "" >> "$GITHUB_STEP_SUMMARY"
Expand Down
238 changes: 238 additions & 0 deletions .github/workflows/release-assets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,17 @@ jobs:
-f net10.0-windows10.0.19041.0
-r win-x64
--self-contained true
-p:VaultSyncReleaseChannel=stable
-p:VaultSyncPackageKind=windows-installer
-p:VaultSyncUpdateSource=github
-p:VaultSyncOfficialBuild=true
-p:VaultSyncSignatureStatus=unsigned
-p:SourceRevisionId=${{ github.sha }}

- name: Verify embedded runtime (win-x64)
run: >
python scripts/runtime_pack_audit.py
--runtimeconfig src/VaultSync.UI/bin/Release/net10.0-windows10.0.19041.0/win-x64/publish/VaultSync.UI.runtimeconfig.json

- name: Install Inno Setup
run: choco install innosetup -y --no-progress
Expand Down Expand Up @@ -435,6 +446,12 @@ jobs:
-f net10.0
-r osx-arm64
--self-contained true
-p:VaultSyncReleaseChannel=stable
-p:VaultSyncPackageKind=macos-dmg
-p:VaultSyncUpdateSource=github
-p:VaultSyncOfficialBuild=true
-p:VaultSyncSignatureStatus=unsigned
-p:SourceRevisionId=${{ github.sha }}

- name: Publish (osx-x64)
run: >
Expand All @@ -443,6 +460,18 @@ jobs:
-f net10.0
-r osx-x64
--self-contained true
-p:VaultSyncReleaseChannel=stable
-p:VaultSyncPackageKind=macos-dmg
-p:VaultSyncUpdateSource=github
-p:VaultSyncOfficialBuild=true
-p:VaultSyncSignatureStatus=unsigned
-p:SourceRevisionId=${{ github.sha }}

- name: Verify embedded runtimes (macOS)
run: >
python3 scripts/runtime_pack_audit.py
--runtimeconfig src/VaultSync.UI/bin/Release/net10.0/osx-arm64/publish/VaultSync.UI.runtimeconfig.json
--runtimeconfig src/VaultSync.UI/bin/Release/net10.0/osx-x64/publish/VaultSync.UI.runtimeconfig.json

- name: Thin architecture-specific native libraries
run: |
Expand Down Expand Up @@ -534,6 +563,12 @@ jobs:
-f net10.0
-r linux-x64
--self-contained true
-p:VaultSyncReleaseChannel=stable
-p:VaultSyncPackageKind=linux-multi-format
-p:VaultSyncUpdateSource=github
-p:VaultSyncOfficialBuild=true
-p:VaultSyncSignatureStatus=unsigned
-p:SourceRevisionId=${{ github.sha }}

- name: Publish (linux-arm64)
run: >
Expand All @@ -542,6 +577,18 @@ jobs:
-f net10.0
-r linux-arm64
--self-contained true
-p:VaultSyncReleaseChannel=stable
-p:VaultSyncPackageKind=linux-multi-format
-p:VaultSyncUpdateSource=github
-p:VaultSyncOfficialBuild=true
-p:VaultSyncSignatureStatus=unsigned
-p:SourceRevisionId=${{ github.sha }}

- name: Verify embedded runtimes (Linux)
run: >
python3 scripts/runtime_pack_audit.py
--runtimeconfig src/VaultSync.UI/bin/Release/net10.0/linux-x64/publish/VaultSync.UI.runtimeconfig.json
--runtimeconfig src/VaultSync.UI/bin/Release/net10.0/linux-arm64/publish/VaultSync.UI.runtimeconfig.json

- name: Build Linux archives
env:
Expand Down Expand Up @@ -620,3 +667,194 @@ jobs:
patches/v${{ inputs.target_version }}/vaultsync-patch-linux-x64.zip
patches/v${{ inputs.target_version }}/vaultsync-patch-linux-arm64.json
patches/v${{ inputs.target_version }}/vaultsync-patch-linux-arm64.zip

release-manifest:
name: Generate canonical release manifest
needs: [validate, windows, macos, linux]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Download direct-release artifacts
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
pattern: "*-release-assets"
path: release-assets
merge-multiple: true

- name: Generate and verify canonical manifest
shell: bash
env:
INCLUDE_LINUX_PATCHES: ${{ inputs.include_linux_patches }}
PREVIOUS_VERSION: ${{ inputs.previous_version }}
RELEASE_CHANNEL: ${{ inputs.release_channel }}
TARGET_VERSION: ${{ inputs.target_version }}
run: |
set -euo pipefail
optional_args=()
if [[ "$INCLUDE_LINUX_PATCHES" == "true" ]]; then
optional_args+=( --include-linux-patches )
fi
python3 scripts/release_manifest.py generate \
--asset-root release-assets \
--output release-assets/vaultsync-release-manifest.json \
--version "$TARGET_VERSION" \
--channel "$RELEASE_CHANNEL" \
--commit "${{ github.sha }}" \
--repository "${{ github.repository }}" \
--previous "$PREVIOUS_VERSION" \
"${optional_args[@]}"
python3 scripts/release_manifest.py validate \
--manifest release-assets/vaultsync-release-manifest.json \
--asset-root release-assets

- name: Upload canonical release manifest
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: canonical-release-manifest
if-no-files-found: error
path: release-assets/vaultsync-release-manifest.json

supply-chain-proof:
name: Generate SBOMs and attest release packages
needs: [release-manifest]
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
attestations: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Setup .NET
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6
with:
dotnet-version: "10.0.x"

- name: Download direct-release artifacts
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
pattern: "*-release-assets"
path: release-assets
merge-multiple: true

- name: Download canonical release manifest
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: canonical-release-manifest
path: release-assets

- name: Resolve dependency graph
shell: bash
run: |
set -euo pipefail
mkdir -p supply-chain/project-assets
for rid in win-x64 osx-arm64 osx-x64 linux-x64 linux-arm64; do
framework=net10.0
if [[ "$rid" == win-x64 ]]; then
framework=net10.0-windows10.0.19041.0
fi
dotnet restore src/VaultSync.UI/VaultSync.UI.csproj \
-p:EnableWindowsTargeting=true \
-p:TargetFramework="$framework" \
-r "$rid"
cp src/VaultSync.UI/obj/project.assets.json "supply-chain/project-assets/$rid.json"
done

- name: Generate and validate SPDX SBOMs
shell: bash
run: |
set -euo pipefail
created="$(git show -s --format=%cI "$GITHUB_SHA")"
python3 scripts/release_sbom.py generate \
--manifest release-assets/vaultsync-release-manifest.json \
--project-assets supply-chain/project-assets \
--output supply-chain/sboms \
--created "$created"
python3 scripts/release_sbom.py validate \
--manifest release-assets/vaultsync-release-manifest.json \
--sbom-root supply-chain/sboms
sed 's# \*# *release-assets/#' \
supply-chain/sboms/vaultsync-release-subjects.sha256 \
> supply-chain/attestation-subjects.sha256

- name: Attest release-package provenance
id: provenance
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-checksums: supply-chain/attestation-subjects.sha256

- name: Attest Windows installer SBOM
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: release-assets/VaultSync-Setup-${{ inputs.target_version }}.exe
sbom-path: supply-chain/sboms/VaultSync-Setup-${{ inputs.target_version }}.exe.spdx.json

- name: Attest macOS Apple silicon SBOM
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: release-assets/VaultSync-${{ inputs.target_version }}-macos-apple-silicon.dmg
sbom-path: supply-chain/sboms/VaultSync-${{ inputs.target_version }}-macos-apple-silicon.dmg.spdx.json

- name: Attest macOS Intel SBOM
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: release-assets/VaultSync-${{ inputs.target_version }}-macos-intel.dmg
sbom-path: supply-chain/sboms/VaultSync-${{ inputs.target_version }}-macos-intel.dmg.spdx.json

- name: Attest Linux x64 archive SBOM
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: release-assets/VaultSync-${{ inputs.target_version }}-linux-x64.tar.gz
sbom-path: supply-chain/sboms/VaultSync-${{ inputs.target_version }}-linux-x64.tar.gz.spdx.json

- name: Attest Linux x64 Debian SBOM
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: release-assets/VaultSync-${{ inputs.target_version }}-linux-x64.deb
sbom-path: supply-chain/sboms/VaultSync-${{ inputs.target_version }}-linux-x64.deb.spdx.json

- name: Attest Linux x64 AppImage SBOM
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: release-assets/VaultSync-${{ inputs.target_version }}-linux-x64.AppImage
sbom-path: supply-chain/sboms/VaultSync-${{ inputs.target_version }}-linux-x64.AppImage.spdx.json

- name: Attest Linux arm64 archive SBOM
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: release-assets/VaultSync-${{ inputs.target_version }}-linux-arm64.tar.gz
sbom-path: supply-chain/sboms/VaultSync-${{ inputs.target_version }}-linux-arm64.tar.gz.spdx.json

- name: Attest Linux arm64 Debian SBOM
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: release-assets/VaultSync-${{ inputs.target_version }}-linux-arm64.deb
sbom-path: supply-chain/sboms/VaultSync-${{ inputs.target_version }}-linux-arm64.deb.spdx.json

- name: Verify online and offline release-candidate provenance
if: ${{ inputs.release_candidate }}
shell: bash
env:
PROVENANCE_BUNDLE: ${{ steps.provenance.outputs.bundle-path }}
TARGET_VERSION: ${{ inputs.target_version }}
run: |
set -euo pipefail
subject="release-assets/VaultSync-Setup-$TARGET_VERSION.exe"
gh attestation verify "$subject" --repo "$GITHUB_REPOSITORY"
gh attestation trusted-root > supply-chain/trusted-root.jsonl
gh attestation verify "$subject" \
--repo "$GITHUB_REPOSITORY" \
--bundle "$PROVENANCE_BUNDLE" \
--custom-trusted-root supply-chain/trusted-root.jsonl

- name: Upload release SBOMs
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: release-supply-chain-proof
if-no-files-found: error
path: |
supply-chain/sboms
supply-chain/trusted-root.jsonl
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,9 @@ docs/localization-missing-keys-report.md
docs/PROJECT_OPERATIONS.md
.codex_tmp_merge_locales.cs
docs/video/build/

# Blueprints local project state (generated when this repository is added)
/.blueprints/
/log/
/project/
/versions
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,37 @@
# Changelog
## [1.8.7] - Unreleased
### Added
- [VS-1871] Added one conservative build-identity record across Settings, startup diagnostics, support and recovery exports, plus `vaultsync --version --json`; version, channel, commit, runtime, architecture, package, update source, official status, and signature status now come from the same contract.
- [VS-1873] Added per-package SPDX 2.3 SBOM generation from the canonical release manifest and RID-specific NuGet graph, pinned GitHub provenance/SBOM attestations for final package bytes, and online plus offline release-candidate verification.
- [VS-1872] Added the versioned canonical release manifest generator and schema, with exact artifact sizes, SHA-256 digests, official download identities, strict platform-matrix validation, deterministic output, release-workflow generation, post-publish verification, and fail-closed updater consumption across Windows, macOS, and Linux artifacts.
- [VS-1877] Added a durable, owner-private installation identity for cross-machine coordination without treating mutable host names or telemetry identifiers as writer identity.
- [VS-1877] Added repository-scoped writer leases with atomic acquisition, heartbeat and expiry, read-only busy inspection, nonce-bound release, explicit stale takeover, and retained takeover evidence.
- [VS-1877] Added per-destination repository-writer inspection and an explicit stale-takeover review that shows the owner, operation, version, heartbeat, and expiry before preserving the old lease as evidence.
- [VS-1879] Added durable per-source merge bases and a field-level three-way metadata planner so independent cross-machine edits merge automatically while overlapping edits remain explicitly reviewable.
- [VS-1879] Added a Base/local/remote conflict table with revision, writer, and timestamp context plus a durable Undo decision action that expires after the next portable repository write.
### Changed
- [BUG-18099] Serviced the .NET 10 baseline to SDK `10.0.303`, runtime `10.0.11`, and coordinated Microsoft packages, with CI auditing real self-contained publishes and release artifacts for every supported runtime identifier.
- [VS-1877] Protected project settings, backup history, tombstones, deferred metadata writes, and deferred flushing with repository lease ownership checks while keeping imports and previews readable when another writer is active.
- [VS-1877] Made unavailable-destination metadata queues fail closed: queued metadata can initialize an empty destination once, while an existing destination is preserved for explicit merge review.
- [VS-1879] Made conflict decisions preserve non-overlapping remote edits, record source and base revisions, and advance the durable merge base after either resolution.
- [VS-1879] Guarded every portable project writer with compare-and-swap revisions and upgraded project records to schema version 3 with base revision, per-field writer/timestamp provenance, and safe resolution evidence.
- [VS-1880] Consolidated metadata export orchestration, SMB mount parsing, mounted-share validation, theme color normalization, and contrast calculations behind focused shared primitives with regression coverage.
- [VS-1880] Unified Windows Robocopy exclusions with the shared preset resolver.
- [BUG-18103] Modernized Snapshot Explorer, metadata-import review, and updater windows around the current compact, theme-aware app layout.
- [BUG-18104] Reworked development presets to preserve Git control files and shareable IDE configuration while excluding live Git internals and modern build, package, test, framework, and machine-local caches.
### Fixed
- [BUG-18098] Rebuilt roadmap description synchronization around tested wrapped-title parsing, ownership-aware body preservation, repository-contained inputs, validated GitHub identifiers, and an exact write-free dry-run report.
- [BUG-18100] Restored `Dev` as the permanent integration branch at the `1.8.6` Stable commit and disabled automatic head-branch deletion so Stable promotion cannot remove it again.
- [BUG-18102] Prevented deferred metadata replay from overwriting repository metadata changed on another machine or replaying repeatedly after a successful flush.
- [BUG-18102] Disabled connection pooling for the repository coordination database so disposed writer leases release their file handles predictably on Windows.
- [BUG-18104] Corrected the Python pytest-cache rule and removed unsupported VS Code negation rules that previously excluded intended shared configuration.
- [BUG-18105] Prevented metadata-import previews from double-counting projects and backups that are represented by both portable metadata and legacy repository folders.
- [BUG-18106] Normalized macOS SMB mount diagnostics to remove the complete credential-bearing share identity before masking any remaining raw or escaped password text.
- [BUG-18107] Stopped metadata import from exporting deletion tombstones for snapshots that were preserved because they still have local backups or never existed locally.
- [BUG-18108] Stopped repeated background downloads of immutable release and platform patch manifests by persisting digest-verified cache entries across application restarts.
- [BUG-18109] Bounded disposable logs, diagnostics, caches, patch runtimes, downloads, and temporary work, and stopped backups from writing into unmounted macOS managed-mount directories on the local system drive.
- [BUG-18101] Made cross-machine project-setting conflicts complete and durable: encryption keys and unmatched destinations stay local, avatar/encryption/auto-backup changes join the review, rejected revisions remain resolved, project writers are recorded per row, and automatic imports cannot apply destructive tombstones without review.

## [1.8.6] - 10.08.2026
### Added
- [VS-1861] Replaced first-run overlays with a compact, resumable task sequence driven by real source, destination, project, schedule, restore-point, and passed recovery-drill state.
Expand Down
Loading
Loading