Skip to content

fix: data integrity fixes (Batch 2)#147

Merged
careck merged 2 commits into
masterfrom
feat/data-integrity-fixes
Apr 22, 2026
Merged

fix: data integrity fixes (Batch 2)#147
careck merged 2 commits into
masterfrom
feat/data-integrity-fixes

Conversation

@careck
Copy link
Copy Markdown
Member

@careck careck commented Apr 22, 2026

Summary

Pre-1.0 audit Batch 2 — fixes 7 data integrity issues plus 1 documentation item. Closes #139.

  • C5: delete_note_recursive now runs deletion + op log in a single atomic transaction (was two separate transactions — crash between them lost sync history)
  • H6: run_migrations wrapped in BEGIN IMMEDIATE / COMMIT to prevent partial migration on crash
  • H7: wall_clock_ms() uses .unwrap_or_default() instead of .unwrap() to avoid panic on pre-epoch system clock
  • M4: ScriptRestore undo variant now captures and restores the original category field instead of hardcoding "library" (fixes schema scripts restoring as library)
  • M5: Default op purge limit increased from 100 → 1000, configurable via workspace_meta key purge_limit
  • M6: set_note_checked now uses chrono::Utc::now().timestamp() (seconds) instead of ts.wall_ms (milliseconds) for modified_at, matching every other write path
  • M7: import_workspace now preserves the original owner_pubkey from the archive instead of overwriting it with the importer's key
  • H5: Added documentation comment to device.rs explaining DefaultHasher instability risk (no code change)

Test plan

  • test_c5_delete_note_logs_operation_atomically — verifies DeleteNote op exists after recursive delete
  • test_m4_undo_delete_schema_script_restores_category — verifies undoing a schema-category script delete restores "schema" not "library"
  • test_m5_purge_retains_more_than_100_ops — verifies 120+ ops survive purge (old limit was 100)
  • test_m6_set_note_checked_stores_seconds_timestamp — verifies modified_at is seconds-range, not milliseconds
  • test_m7_import_preserves_original_owner_pubkey — exports with key A, imports with key B, verifies owner is still key A
  • All 600 existing tests pass

careck added 2 commits April 22, 2026 15:45
C5: Make delete_note_recursive atomic — merge deletion and op log into
    a single transaction to prevent sync history loss on crash.
H6: Wrap run_migrations in BEGIN IMMEDIATE / COMMIT so partial
    migration on crash is rolled back.
H7: Replace .unwrap() with .unwrap_or_default() in wall_clock_ms()
    to avoid panic when system clock is pre-epoch.
M4: Add category field to ScriptRestore undo variant so undoing a
    schema-category script delete restores the correct category
    instead of hardcoding "library".
M5: Increase default op purge limit from 100 to 1000, configurable
    via workspace_meta 'purge_limit' key.
M6: Replace ts.wall_ms (milliseconds) with chrono::Utc::now().timestamp()
    (seconds) in set_note_checked to match every other write path.
M7: Preserve original owner_pubkey on workspace import by including it
    in the export archive and restoring it after Workspace::open().
H5: Document DefaultHasher instability in device.rs (no code change).

Closes #139
Auto mode checked only hasPeers (from list_workspace_peers) which may
silently fail at startup.  Also consider shareAnchorIds — if the owner
has granted RBAC permissions, indicators should appear regardless.

Add console.warn to the silent .catch so failures are visible in devtools.
@careck careck merged commit 68b6202 into master Apr 22, 2026
@careck careck deleted the feat/data-integrity-fixes branch April 22, 2026 08:44
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.

Data Integrity Fixes

1 participant