Context
ROADMAP.md explicitly lists the next Local-First phases from ADR-0008 as:
B2.1 — migrate manuscript text to Y.Text
B2.2 — flip the source of truth behind enableLocalFirstSync
The repository already has Yjs/Local-First infrastructure and observation/shadow behavior, but there is no durable issue that owns this later text-authority migration. Issue #548 is intentionally much narrower: it tracks prototype-named entity IDs in the existing Yjs reconstruction path and must not become the umbrella for B2.
Goal
Move manuscript text toward Y.Text in a staged, reversible, evidence-driven way, then permit a source-of-truth switch only after deterministic parity and recovery gates pass.
The migration must preserve current user data and editing semantics. It must not treat “Yjs exists in the repository” as proof that Yjs is already safe to become authoritative for manuscript text.
Phase B2.1 — Y.Text migration proof
Define the smallest renderer-neutral manuscript-text representation and adapter boundary required to mirror current authoritative editor/project state into Y.Text.
Prove at minimum:
- exact text content round-trips without normalization drift;
- section/document identity remains stable;
- ordering and structural metadata remain intact;
- Unicode/grapheme/line-ending behavior is deterministic;
- edits applied through current editor transactions produce the expected Y.Text state;
- Yjs updates can reconstruct the same current project state without dropping unknown/unmodeled project fields;
- project switching cannot apply stale updates to another project;
- teardown/reopen/restart does not leak observers or duplicate updates;
- large manuscript behavior remains bounded and editor responsiveness is protected.
During B2.1 the current project state remains authoritative unless an explicitly admitted narrower vertical slice says otherwise.
Phase B2.2 — source-of-truth admission
Do not flip enableLocalFirstSync into production authority merely because shadow parity is green in a few unit fixtures.
Required admission gates include:
NO-LOSS ROUND TRIP
DETERMINISTIC CURRENT↔Y.TEXT PARITY
UNDO/REDO SEMANTICS DEFINED
PROJECT-SWITCH STALE-UPDATE PROTECTION
PERSISTENCE/RESTART RECOVERY
OFFLINE BEHAVIOR
MULTI-WINDOW/TAB AUTHORITY WHERE APPLICABLE
ROLLBACK/FALLBACK PATH
OBSERVABILITY WITHOUT MANUSCRIPT LEAKAGE
The switch must be reversible during rollout. Persisted data written by the new authority must not strand users who fall back to the previous application version/path unless that compatibility break is explicitly versioned and migrated.
Undo/history contract
Before authority changes, reconcile:
- current Redux/project undo semantics;
- Yjs transaction origins;
- local undo manager behavior if used;
- editor command grouping;
- startup repair/migration transactions;
- remote/collaborative update behavior.
Do not silently create two independent undo histories that both appear authoritative.
Persistence and recovery
Define exactly what is persisted and where for the admitted phase:
- canonical project snapshot/state;
- Yjs update log/state vector if retained;
- compaction/checkpoint behavior;
- corruption/incomplete-write recovery;
- migration from existing projects;
- rollback after interrupted migration.
Coordinate browser writer/concurrency semantics with #480 where the PWA actually has multiple tabs/windows. Do not make #480 the generic Local-First text-architecture owner.
Relationship to collaboration
Yjs-based real-time collaboration and Local-First manuscript authority overlap technically but are not the same product contract.
Do not fold invite-link UX (#349) or unrelated collaboration features into this migration. Shared CRDT primitives may be reused, but authority, persistence and recovery acceptance must be explicit for Local-First text.
Relationship to current issues
Regression/evidence matrix
At minimum cover:
- empty manuscript;
- single and many sections;
- very large text;
- Unicode/RTL/emoji/graphemes;
- rapid edit bursts;
- undo/redo grouping;
- project switch during pending update;
- app reload/restart;
- interrupted persistence/compaction;
- offline edit and resume;
- two active views where the platform permits it;
- old/current persisted project migration;
- rollback from shadow/new-authority mode;
- malformed/foreign Yjs state failing safely rather than replacing valid project data.
Acceptance criteria
Non-goals
- rewriting the entire project domain around Yjs in one PR;
- implementing collaboration invite UX;
- making Local-First synonymous with cloud sync;
- starting a source-of-truth flip before shadow/evidence gates pass;
- moving AI services into Rust;
- coupling the migration to Qt implementation timing.
Context
ROADMAP.mdexplicitly lists the next Local-First phases from ADR-0008 as:The repository already has Yjs/Local-First infrastructure and observation/shadow behavior, but there is no durable issue that owns this later text-authority migration. Issue #548 is intentionally much narrower: it tracks prototype-named entity IDs in the existing Yjs reconstruction path and must not become the umbrella for B2.
Goal
Move manuscript text toward Y.Text in a staged, reversible, evidence-driven way, then permit a source-of-truth switch only after deterministic parity and recovery gates pass.
The migration must preserve current user data and editing semantics. It must not treat “Yjs exists in the repository” as proof that Yjs is already safe to become authoritative for manuscript text.
Phase B2.1 — Y.Text migration proof
Define the smallest renderer-neutral manuscript-text representation and adapter boundary required to mirror current authoritative editor/project state into Y.Text.
Prove at minimum:
During B2.1 the current project state remains authoritative unless an explicitly admitted narrower vertical slice says otherwise.
Phase B2.2 — source-of-truth admission
Do not flip
enableLocalFirstSyncinto production authority merely because shadow parity is green in a few unit fixtures.Required admission gates include:
The switch must be reversible during rollout. Persisted data written by the new authority must not strand users who fall back to the previous application version/path unless that compatibility break is explicitly versioned and migrated.
Undo/history contract
Before authority changes, reconcile:
Do not silently create two independent undo histories that both appear authoritative.
Persistence and recovery
Define exactly what is persisted and where for the admitted phase:
Coordinate browser writer/concurrency semantics with #480 where the PWA actually has multiple tabs/windows. Do not make #480 the generic Local-First text-architecture owner.
Relationship to collaboration
Yjs-based real-time collaboration and Local-First manuscript authority overlap technically but are not the same product contract.
Do not fold invite-link UX (#349) or unrelated collaboration features into this migration. Shared CRDT primitives may be reused, but authority, persistence and recovery acceptance must be explicit for Local-First text.
Relationship to current issues
Regression/evidence matrix
At minimum cover:
Acceptance criteria
ROADMAP.md/ ADR-0008 status is updated only when the actual admission state changes.Non-goals