Skip to content

Data Integrity Fixes #139

@careck

Description

@careck

Pre-1.0 Audit — Batch 2

Priority: Critical
Spec: docs/superpowers/specs/2026-04-22-pre-1.0-audit-remediation-design.md

Issues Addressed

  • C5delete_note_recursive commits deletion and op log in separate transactions — crash between them loses sync history (workspace/notes.rs:1317-1340)
  • H6 — DB migrations not wrapped in a transaction — partial migration risk (storage.rs:101-458)
  • H7wall_clock_ms() panics if system clock is pre-epoch (hlc.rs:113-118)
  • M4ScriptRestore during undo hardcodes category as "library" (workspace/undo.rs:538-549)
  • M5 — Op purge strategy at 100 is too aggressive for sync-enabled workspaces (workspace/mod.rs constructors)
  • M6set_note_checked stores HLC milliseconds in modified_at instead of seconds (workspace/notes.rs:892-893)
  • M7import_workspace sets importer as owner, bypassing original authorship (export.rs:517-551)
  • H5DefaultHasher instability in device.rsdocument only, no code change. Battle-tested for multi-device sync.

Key Fixes

  • C5: Advance HLC and clone signing key before opening the transaction. Run deletion and op log in one tx.
  • H6: Wrap run_migrations in BEGIN IMMEDIATE / COMMIT.
  • M4: Add category: String to ScriptRestore variant. Capture original category on undo entry creation.
  • M5: Increase default purge limit to 1000 for sync-enabled workspaces (configurable via workspace_meta).
  • M6: Replace ts.wall_ms as i64 with chrono::Utc::now().timestamp().
  • M7: Preserve original owner_pubkey from imported workspace metadata.

Testing

  • C5: Verify op exists after delete (atomic transaction test)
  • H6: Test migration rollback on simulated mid-migration failure
  • M4: Test undoing a schema-category script delete restores correct category
  • M5: Test purge strategy respects configured limit
  • M6: Test set_note_checked writes a seconds-range timestamp
  • M7: Test importing preserves original owner_pubkey

Depends on

Batch 1 (Workspace Constructor Refactor) — constructor refactor simplifies M5 fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpre-1.0 auditPre-1.0 release audit remediation

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions