Skip to content

feat: local-only schema fields (not synced to peers) #166

@careck

Description

@careck

Summary

Allow schema field definitions to declare local_only: true, so that field values are stored locally but never synced to peers via delta bundles or snapshots. Each peer sees the same schema but stores their own independent values for local-only fields.

Use Cases

  • Personal annotations on shared notes (e.g. my_notes, my_rating)
  • Draft/scratch fields that aren't ready for peers to see
  • Private metadata on shared data structures

Rhai Schema Example

schema("SharedDocument", #{
    version: 1,
    fields: [
        #{ name: "content",    type: "textarea" },
        #{ name: "status",     type: "select", options: ["Draft", "Review", "Final"] },
        #{ name: "my_notes",   type: "textarea", local_only: true },
        #{ name: "my_rating",  type: "rating", max: 5, local_only: true },
    ]
});

Design Decisions

  • Schema-definedlocal_only: true on a field def. Owner defines it, all peers see the field exists
  • Each peer stores their own values — field exists for everyone, values never leave the device
  • Sync filteringUpdateField ops targeting local-only fields excluded from delta bundles and snapshots. CreateNote ops have local-only field values stripped before sync
  • Undo/redo — works normally locally (ops still in local log)
  • Export — user chooses whether to include local-only field data (checkbox in export dialog)
  • Import — if local-only data is present in archive, import it; if absent, fields start empty
  • RBAC interaction — orthogonal. Schema owner defines which fields are local-only; RBAC controls note visibility

Implementation Plan

docs/superpowers/plans/2026-04-29-local-only-fields.md

10 tasks:

  1. Add local_only to FieldDefinition + Rhai parsing
  2. Helper method is_field_local_only
  3. Filter UpdateField ops from operations_since / operations_since_with_verified_by
  4. Strip local-only fields from CreateNote ops in sync
  5. Strip local-only fields from workspace snapshots
  6. Add include_local_only option to export (Rust + Tauri command)
  7. Frontend: TS type + UI indicator on local-only fields
  8. Frontend: export dialog checkbox for including local-only data
  9. Update SCRIPTING.md documentation
  10. Full round-trip integration test

Files Touched

Rust core: schema.rs, sync.rs, export.rs, lib.rs, tests.rs
Tauri: commands/workspace.rs
Frontend: types.ts, InfoPanel.tsx, App.tsx, all 7 locale files
Docs: SCRIPTING.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions