- Update hybrid-manifest-architecture.md status to Implemented
- Add documentation index (README.md) for operation-log docs
- Add index for docs/ai/sync/ with document categorization
- Replace duplicate docs with redirect stubs to canonical locations
- Add effect rules, multi-entity rules, and config constants to operation-rules.md
- Update vector-clocks.md with operation log integration section
- Expand super-sync-server README with API details and security features
- Update pfapi sync README with operation log integration info
- Add Section 2c to architecture diagrams with mermaid diagrams
explaining the late-joiner problem and solution
- Add Section C.7 to main architecture doc with code examples
- Add Example 4 to vector-clocks.md explaining dominance filtering
- Update Last Updated dates to December 12, 2025
Add class-level documentation explaining:
- Only SuperSync uses operation log sync (API-based)
- Legacy providers skip operation log sync entirely
- File-based methods exist for future extensibility but are never called
- If file-based sync is ever enabled, encryption/decryption must be added
The original review incorrectly identified file-based operation log sync
as having "critical gaps". This update corrects the analysis:
- File-based operation log sync is dead code, never called
- Only SuperSync uses operation log sync (API-based)
- Legacy providers skip operation log sync entirely and use pfapi LWW
Status changed from "NEEDS FIXES" to "PRODUCTION READY"
Mark all previously identified test gaps as resolved:
- Race conditions: 6 new tests in compaction service
- Schema migration: 6 version mismatch tests in hydrator service
- Download retry: 4 tests now passing (was pending())
- All critical and missing scenarios now have test coverage
- Add December 11 security review results (all issues verified as addressed)
- Document newly added tests (3-way conflict, delete vs update, large conflict sets)
- Update test coverage status table with completed items
- Mark supersync E2E test plan as IMPLEMENTED
- List all test files and their coverage areas
Update documentation to reflect recent simplifications:
- OperationCaptureService now uses simple FIFO queue
- OperationApplierService uses fail-fast approach
- ArchiveOperationHandler is unified for local and remote operations
- Update diagrams and file references
- Add "Recently Completed" items for December 2025
Consolidate all archive-affecting operations into ArchiveOperationHandler
to eliminate duplicate code and create a single source of truth.
Changes:
- Add ArchiveOperationHandlerEffects for local operations
- Rename handleRemoteOperation to handleOperation
- Add isArchiveAffectingAction helper for action filtering
- Make isIgnoreDBLock conditional on action.meta.isRemote
- Remove archive logic from individual effect files
- Update feature-stores.module.ts to use new effect
- Add archive write points documentation
This ensures archive operations (moveToArchive, restoreTask,
flushYoungToOld, deleteProject, deleteTag, deleteTaskRepeatCfg,
deleteIssueProvider) all go through one handler for both local
and remote operations.
Analysis shows the alleged race conditions are intentional defensive patterns:
- Double sync wait ensures stability during date changes
- Effects are complementary with staggered timing, not competing
- Infinite loop scenario explicitly handled in code
Note: Tests exist but are disabled due to Dropbox SDK mocking issues.
Re-evaluated the "missing subtask cascade in tag deletion" issue.
The current behavior is correct:
- A subtask with a surviving parent is NOT orphaned - it's accessible
through the parent in the UI
- If a parent is orphaned, its subtasks ARE correctly deleted
- Subtasks always have parentId, so they're never directly orphaned
This is intentional behavior, not a bug.
The snapshot was being saved before validation ran. If validation found
corruption and repaired it, the snapshot was stale/wrong. This fix
moves validation (CHECKPOINT C) BEFORE saving snapshot in both:
- Tail replay path (after replaying ops following a snapshot)
- Full replay path (when no snapshot exists)
Now the snapshot contains validated/repaired state.
Includes regression tests that verify validation happens before snapshot
save in both code paths.
The incrementCompactionCounter() function returned 1 without persisting
when no state cache existed. This caused the compaction threshold to
never be reached, leading to unbounded operation log growth.
Also updated review docs:
- Marked compaction counter bug as fixed
- Identified memory leak in TaskElectronEffects as false positive
(take(1) ensures automatic cleanup)
- Identified TODAY_TAG "board-style" claim as false positive
(code correctly REMOVES TODAY_TAG from task.tagIds)
- Identified cache invalidation claim as false positive
(sequence-based invalidation works correctly)
- Identified repair mutex race condition as false positive
(JavaScript single-threaded, no await between assignment)
Tasks created without explicit dueDay don't appear in TODAY view
due to recent selector changes. Add sd:today short syntax to ensure
tasks have dueDay set and appear correctly in tests.
Add Karma-based integration tests for the operation log system using real
IndexedDB. Tests cover multi-client synchronization scenarios and state
consistency verification.
New test files:
- multi-client-sync.integration.spec.ts (16 tests)
- state-consistency.integration.spec.ts (17 tests)
Test utilities:
- TestClient helper for simulating multiple clients with independent vector clocks
- Operation factory helpers for creating test operations
- Add unit tests for isPersistentAction type guard.
- Fix compilation errors in task scheduling components caused by removed reminderId/removeReminderFromTask.
- Fix type error in create-sorted-blocker-blocks.spec.ts.
- Fix lint errors in various files.
- Add syncTimeSpent persistent action for batched time tracking sync
- Accumulates duration per task, syncs every 5 minutes or on task stop
- Local dispatch: no-op (state already updated by second-by-second ticks)
- Remote dispatch: applies batched duration to task.timeSpentOnDay
- Fix remote archive handling to include time tracking data
- writeTasksToArchiveForRemoteSync now moves historical time tracking
data to archiveYoung alongside tasks
- Add flushYoungToOld persistent action for deterministic archive state
- Replaces inline flush logic with action-based approach
- Remote clients replay the flush operation to maintain consistent
archiveOld state without syncing large files
- Vector clock ordering ensures flush happens after preceding operations
- Implement processRemoteOps migration logic in OperationLogSyncService using SchemaMigrationService.
- Add MAX_VERSION_SKIP check and user warning via SnackService.
- Fix Log class to support dynamic level switching (fixes PFAPI tests).
- Fix operation-log-stress imports.
- Skip disabled MultiTabCoordinatorService tests.
- Add unit tests for migration logic.
- Update ValidateStateService documentation to reflect better error handling for isRelatedModelDataValid.
- Update Part C status to Complete as Server Sync is implemented.
- List implemented components for Part C.
- Fix lint error in startup.service.ts
- Store compaction counter in state_cache to share across tabs/restarts
- Add bySyncedAt index for faster getUnsynced() queries
- Remove in-memory opsSinceCompaction counter from effects
- Reset counter in compaction service after successful compaction
Implements A.7.12, A.7.13, and A.7.15 from the operation log architecture:
- A.7.12 Migration Safety: Backup state_cache before migration, restore
on failure, detect interrupted migrations on startup
- A.7.13 Tail Ops Migration: Migrate operations to current schema before
replay during hydration
- A.7.15 Unified Interface: Extend SchemaMigration with migrateOperation
and requiresOperationMigration for explicit migration decisions
Changes:
- operation-log-store: Add backup/restore methods for state_cache
- schema-migration: Add operation migration support and validation
- operation-log-hydrator: Integrate backup safety and tail ops migration
- Update architecture docs to reflect implementation status
Document the relationship between state migrations (for snapshots) and
operation migrations (for tail ops/sync). Key points:
- Single SchemaMigration interface with both migrateState and migrateOperation
- requiresOperationMigration flag forces explicit decision
- Startup validation catches missing operation migrations
- Examples for field rename and feature removal migrations
- Explains why auto-derivation doesn't work (UPDATE payloads differ from entities)
- Updated implementation status table with A.7.15
- Fix status claims: Part A "Functional" (not Complete), Part C "Design Only"
- Add Known Gaps callout for critical unimplemented features (A.7.12, A.7.13)
- Fix code bug in C.5 conflict resolution (variable out of scope)
- Fix broken markdown (4 backticks instead of 3)
- Add "Edge Cases & Missing Considerations" section:
- IndexedDB quota exhaustion handling
- Compaction trigger coordination between tabs
- Genesis migration with partial data
- Restructure Implementation Status by Part (A, B, C, D)
- Add note to diagrams doc clarifying planned vs implemented features
- Fix mermaid syntax errors in hybrid manifest diagram
Introduces a new documentation file detailing the Hybrid Manifest and Snapshot architecture
designed to improve efficiency for file-based sync providers like WebDAV and Dropbox.
This approach reduces API requests and file proliferation by embedding small operations
directly into the manifest file and periodically consolidating changes into snapshots.
Also updates the architecture diagrams to include a visualization of this new hybrid approach.
Additionally, a "Conflict-Aware Migration Strategy" section was added to the existing
operation-log-architecture.md during initial codebase investigation to provide further
context on managing schema version differences during sync.
Integrate PFAPI's validation/repair with operation logs to prevent
corruption and automatically recover from invalid states.
Key features:
- REPAIR operation type with full repaired state + summary
- 4 validation checkpoints (A: before write, B: after snapshot load,
C: after replay, D: after sync)
- Payload validation before IndexedDB write (lenient structural checks)
- Full Typia + cross-model validation at state checkpoints
- User notification when auto-repair occurs
- Infinite loop prevention during repair
New files:
- validate-state.service.ts: wraps PFAPI validation + repair
- validate-operation-payload.ts: checkpoint A payload validation
- repair-operation.service.ts: REPAIR operation creation
Replace custom UUID v7 implementations with the standard uuidv7 library.
The custom implementation had a bug with JavaScript bitwise operators
not handling 48-bit timestamps correctly.