Skip to main content

Changelog

Every improvement, automatically tracked from our commit history.

Subscribe via Atom feed
← Prev Page 7 of 139 Next →
March 1, 2026
patch Desktop ShellServices

Fix Subsystems tab: use process-level native memory, improve column layout

Desktop 1.69.0 | Services 1.68.6 | 086dcb9a
Details

The "Native Memory" summary card was showing only Rust allocator-tracked

bytes (~126 B), which is misleading when the process uses ~1.4 GB native.

The Rust GlobalAlloc only tracks Rust heap allocations — C/C++ libraries

(SQLCipher, ONNX, Whisper, LLamaSharp) use their own malloc directly.

  • Summary "Native Memory" card now uses WorkingSet64 - GC heap (same

calculation as the Overview tab's memory card)

  • Per-subsystem memory column renamed to "Tracked Memory" and widened

to accommodate labels like "126 B native" or "7.0 MB managed"

  • Memory display now distinguishes native vs managed with explicit labels
  • Column widths adjusted (Category 80, Tasks 60, Memory 180, Rate 100)
  • Removed broken heartbeat approach for long-running task alloc tracking

(GC.GetAllocatedBytesForCurrentThread can't be queried cross-thread)

minor CoreDesktop ShellServices

Add per-subsystem memory tracker and Dashboard Subsystems tab

Core 1.15.3 → 1.15.4 | Desktop 1.68.6 → 1.69.0 | Services 1.68.6 | 7180a425
Details

Adds visibility into which subsystems consume memory across .NET managed

heap, native Rust allocations, and background task activity. Enables

live per-subsystem metrics in the Dashboard.

Rust tracking allocator (Phase 1):

  • New allocator.rs: custom GlobalAlloc with 16-byte header per allocation

storing size + subsystem ID. Per-subsystem atomic counters track bytes

and allocation counts. Thread-local subsystem tag set via with_subsystem()

scope guard.

  • Subsystem IDs: untagged(0), storage(1), sync(2), crypto(3), cloud(4),

plugins(5), ffi(6), reserved(7)

  • New FFI export: privstack_subsystem_memory() returns JSON snapshots
  • Key entry points wrapped: privstack_execute (FFI), auth_initialize/unlock

(Crypto), sync_status (Sync)

C# SubsystemTracker (Phase 2):

  • SubsystemTracker: singleton service with AsyncLocal tagging, RunTagged()

for async/sync task wrapping, EnterScope() for synchronous code blocks,

5-sample rolling allocation rate, native counter merging from Rust FFI

  • SubsystemDefinitions: static table of 16 built-in subsystems across

UI, AI, Core, Services, and Runtime categories

  • Static RunTaggedStatic() convenience for instrumentation without DI

Entry point instrumentation (Phase 3):

  • RagIndexService: consumer + deferred init tagged as ai.rag
  • IntentEngine: signal consumer tagged as ai.intent
  • EmbeddingService: ONNX load + tokenizer tagged as ai.embedding
  • LocalLlamaProvider: model load tagged as ai.llm
  • WhisperService: model load tagged as ai.whisper
  • IpcServer: listener tagged as ipc
  • ReminderSchedulerService: initial poll tagged as reminders
  • FileEventInboundScanner: poll loop tagged as core.sync
  • SyncOutboundService: debounce callback tagged as core.sync
  • CloudSyncSettingsViewModel: push + status loop tagged as core.cloud
  • UpdateViewModel: startup check tagged as updates

Dashboard Subsystems tab (Phase 4):

  • New SubsystemItemViewModel with status dot coloring (active/idle/stopped)
  • DashboardViewModel extended with Subsystems tab, summary cards (threads,

managed heap, native memory, active count), per-subsystem item collection

  • DashboardView.axaml: third tab button, summary stat cards, table-style

subsystem list with status dot, name, category, task count, memory,

alloc rate columns

  • Live refresh on 1-second timer when Subsystems tab is active

Registration wiring (Phase 5):

  • SubsystemTracker registered as singleton in CoreServiceRegistration
  • Static subsystems registered at startup, eagerly resolved in WireCorePostBuild
  • Plugin subsystems registered dynamically in DashboardPlugin.CreateViewModelCore()
  • NativeLibrary P/Invoke added for privstack_subsystem_memory

Version bumps:

  • Rust workspace: 1.15.3 → 1.15.4
  • Desktop app: 1.68.6 → 1.69.0
  • Dashboard plugin: 1.4.0 → 1.5.0
patch Desktop ShellServerServices

Fix disabled plugins not showing in Settings for re-enable

Server 1.68.6 | Desktop 1.68.6 | Services 1.68.6 | 888dfc6f
Details

Root cause: when a plugin is disabled, its assembly is deferred (not

loaded) at startup to save memory. But the Settings plugin list only

iterated over loaded plugins (_plugins), so deferred plugins were

invisible — the user could never re-enable them.

Fix:

  • Expose DeferredPluginDirs on IPluginRegistry — maps plugin IDs to

their discovered directory paths for plugins that were skipped

  • SettingsViewModel.LoadPluginItems() now appends deferred plugins to

the list with IsEnabled=false, allowing the user to toggle them on

  • Toggling on triggers the existing EnablePlugin() deferred path which

dynamically loads the assembly from the saved directory

  • HeadlessPluginRegistry implements the new property with an empty dict
patch CoreDesktop ShellServices

Fix fresh-install StorageError and update C# paths for SQLite migration

Core 1.15.3 | Desktop 1.68.6 | Services 1.68.6 | 1de039e7
Details

Root cause: on fresh install (no salt file, no existing DB), init_core()

opened an unencrypted on-disk database at data.privstack.db. When

auth_initialize() then tried to create an encrypted DB at the same path,

SQLCipher failed because the file already existed as unencrypted.

Fix (Rust FFI):

  • Fresh install now opens in-memory placeholder (same as encrypted mode)
  • Only open unencrypted on-disk for legacy databases that already exist
  • auth_initialize detects legacy unencrypted DB and skips SQLCipher

creation, just initializes vault on the existing DB

Fix (C# Desktop):

  • WorkspaceService: base path changed from "data.duckdb" to "data"

(Rust derives "data.privstack.db" via with_extension)

  • SetupWizardViewModel: same path change
  • PrivStackService: updated diagnostics to check .privstack.db,

.datasets.db, .privstack.salt instead of old .duckdb files

  • App.axaml.cs: updated orphan cleanup patterns and diagnostics
  • DashboardViewModel: updated file size checks and compact display
  • SystemMetricsService: updated file paths, WAL suffix (.wal → -wal)
patch Core

Add legacy DuckDB migration detection FFI exports

Core 1.15.3 | 33ae1900
Details

Since the Rust core no longer includes the DuckDB library, migration

from old .duckdb files must be orchestrated from the C# managed side.

These FFI functions support that workflow:

  • privstack_has_legacy_databases(path) → bool: detects if any .duckdb

files exist at the data path

  • privstack_list_legacy_databases(path) → JSON array of found files

with names, paths, and sizes

  • privstack_archive_legacy_databases(path): renames .duckdb files to

.duckdb.bak after successful migration, removes stale WAL files

The C# side should check for legacy databases on first launch with the

new version, run its migration logic (reading DuckDB via its own driver

and writing to the new SQLite/SQLCipher database), then call archive

to move the old files out of the way.

← Prev Page 7 of 139 Next →

Get notified about new releases