Commit graph

41 commits

Author SHA1 Message Date
Johannes Millan
b6b51707d3 docs: clean up and organize project documentation
- Remove outdated feature requests from .github/CONTRIBUTING.md (GitLab
  support already exists) and add commit message format section
- Improve PR template with type-of-change checkboxes and checklist
- Update commit guideline links in README and CONTRIBUTING.md to
  reference the project's own format instead of external angular.js docs
- Add "only edit en.json" rule to TRANSLATING.md and clarify workflow
- Update add-new-integration.md provider list to match codebase (add
  Trello, ClickUp, Linear, Azure DevOps, Nextcloud Deck; note GitHub
  plugin migration; fix type name to BuiltInIssueProviderKey)
- Add cross-references between mac certificate docs and remove 240-line
  duplicate section from update-mac-certificates.md
- Clean up update-android-app.md (specify npm version args, collapse
  deprecated workflow, translate German UI labels to English)
- Add context to howto-refresh-snap-credentials.md
- Fix fine-grained token note in github-access-token-instructions.md
- Fix absolute URL to relative path in gitlab-access-token-instructions.md
- Fix grammar in i18n-script-usage.md
- Add status headers to all 19 long-term plan files (Planned, Completed,
  Archived with reason, Investigation Complete)
- Fix broken relative link in hybrid-manifest-architecture.md
- Delete supersync-scenarios-simplified.md (duplicate of
  supersync-scenarios.md; known issues already covered there)
- Rename vector-clock-pruning-research.md to
  vector-clock-history-and-alternatives.md for clarity
2026-03-10 10:22:56 +01:00
Johannes Millan
ab8b577c10 docs(sync): add file-based sync flowchart for Dropbox/WebDAV/LocalFile
Parallel to the SuperSync flowchart, covering the file-based sync
decision tree: gap detection, snapshot hydration, rev-based upload
retry, and error handling. Verified against source code with matching
abstraction level to the SuperSync chart.
2026-03-01 21:27:08 +01:00
Johannes Millan
058c26594b docs(sync): fix structural inaccuracies in supersync scenarios flowchart
Correct the flowchart to match actual codebase behavior:
- Move fresh-client dialogs under the "has remote ops" branch (was incorrectly under "no remote ops")
- Split single password dialog into two distinct decrypt error dialogs (DecryptNoPasswordError vs DecryptError)
- Route SYNC_IMPORT conflicts to ImportConflictDialog (was incorrectly using SyncConflictDialog)
- Add encryption-only change bypass for password-change SYNC_IMPORTs
- Add LWW tie-breaking details (remote wins on tie, archive ops always win)
- Add retry limit note on re-download, correct "Cancel" to "Disable SuperSync"
- Show silent server migration path for fresh clients with local data on empty server
2026-03-01 21:27:08 +01:00
Johannes Millan
b820055b3e docs(sync): distinguish dialog types and highlight actions in flowchart
Rename generic "Conflict dialog" labels to SyncConflictDialog and
ImportConflictDialog to reflect the two distinct components. Add orange
action styling for key state-changing nodes (apply, force upload/download,
enable encryption, upload).
2026-03-01 21:27:08 +01:00
Johannes Millan
dafee46f7a docs(sync): add encryption architecture and scenario documentation
Add comprehensive documentation for the encryption and sync features:

- Add SuperSync encryption architecture document
- Add SuperSync scenario spec with flowcharts
- Add simplified scenario reference
- Add SuperSync client simplification plan
2026-03-01 21:27:08 +01:00
Johannes Millan
9328156ca1 fix(sync): add vector clock pruning to compaction and update docs
Add limitVectorClockSize to OperationLogCompactionService._doCompact()
which was the remaining saveStateCache caller that persisted unpruned
clocks. Update vector-clocks.md exhaustive pruning table with the three
new client-side pruning locations. Add boundary tests at exactly
MAX_VECTOR_CLOCK_SIZE for snapshot and hydrator services.
2026-02-15 11:19:22 +01:00
Johannes Millan
c70ced204e fix(sync): fix stale comments, doc refs, and preserve lastSeq on clean-slate
Remove references to deleted docs/ai/ files, update stale comments about
protectedClientIds and pruning-aware comparison to reflect current REPLACE
semantics, fix MAX=30→20 heading, client_0..29→19 comment, use ?? over ||,
preserve lastSeq in server clean-slate path to prevent sequence reuse, and
add clarifying comments for mock limitations and validation guards.
2026-02-12 16:27:56 +01:00
Johannes Millan
3f99e3773c fix(sync): fix replaceToken expiry, locale-independent sort, and stale comments
- Use JWT_EXPIRY_PASSKEY (7d) for replaceToken instead of 365d magic link
  expiry — token replacement is a security action, shorter lifetime is safer
- Replace localeCompare with locale-independent comparator in vector clock
  tie-breaking to ensure deterministic behavior across environments
- Fix 5 additional stale MAX=30 references in docs and tests (now 20)
- Update authentication.md to reflect dual JWT expiry tiers
- Clean up isLikelyPruningArtifact references in docs and LEGACY_MAX in tests
2026-02-12 16:27:55 +01:00
Johannes Millan
a335589dc6 refactor(sync): reduce vector clock DoS cap from 100 to 50 entries 2026-02-12 16:27:55 +01:00
Johannes Millan
f37280e082 refactor(sync): reduce MAX_VECTOR_CLOCK_SIZE from 30 to 20
Lower the cap to leave headroom for future increases and surface
size-related edge cases earlier. All pruning logic is MAX-agnostic
so this is a safe constant change with documentation updates.
2026-02-12 16:27:55 +01:00
Johannes Millan
128ebe1f8a docs(sync): update stale MAX=10 and pruning-aware references in documentation 2026-02-12 16:27:55 +01:00
Johannes Millan
75a4102937 docs(sync): update pruning research to reflect MAX=30 simplification 2026-02-12 16:27:55 +01:00
Johannes Millan
29541951a3 refactor(sync): increase MAX_VECTOR_CLOCK_SIZE from 10 to 30 and remove defense layers
At MAX=10, pruning triggered frequently enough (11+ unique client IDs from
reinstalls/new browsers) to require 4 defense layers compensating for
information loss: pruning-aware comparison, protected client IDs with
migration, isLikelyPruningArtifact heuristic, and same-client check.

At MAX=30, pruning almost never triggers (needs 31+ unique client IDs).
A 30-entry clock is ~500 bytes — negligible bandwidth. This allows removing
most defense layers while keeping two cheap backward-compat checks for old
10-entry pruned data still on servers.

Removed:
- Pruning-aware mode in compareVectorClocks (standard comparison now)
- Protected client IDs mechanism (storage, migration, preservation)
- selectProtectedClientIds function
- Clock normalization in SyncImportFilterService

Kept temporarily (backward compat with old 10-entry data):
- isLikelyPruningArtifact with LEGACY_MAX=10
- Same-client check (always mathematically correct)
2026-02-12 16:27:55 +01:00
Johannes Millan
48924428c6 docs(sync): rewrite vector clocks architecture document from scratch
Replace the scattered, contradictory document with a coherent 13-section
architecture reference covering the full vector clock system: core
operations, pruning, conflict detection, SYNC_IMPORT filtering, defense
layers against pruning artifacts, and step-by-step scenario traces.
2026-02-12 16:27:55 +01:00
Johannes Millan
4a779a0218 fix(sync): replace vector clock on remote SYNC_IMPORT instead of merging
When a client with an established vector clock (10+ entries) received a
remote SYNC_IMPORT/BACKUP_IMPORT with a fresh clock, mergeRemoteOpClocks()
merged the import's clock into the old clock instead of replacing it.
This caused clock bloat (11+ entries), which led to server-side pruning
dropping the import's entry (lowest counter). Other clients then saw
these ops as CONCURRENT with the import and discarded them.

Fix: In mergeRemoteOpClocks(), when a full-state op is present, use its
clock as the base instead of the existing local clock. Regular ops
continue to merge normally.
2026-02-12 16:27:55 +01:00
Johannes Millan
fc56aabec4 docs(sync): fix stale DoS cap references from 3x to 5x MAX_VECTOR_CLOCK_SIZE
The sanitizeVectorClock() DoS cap was changed to 5x MAX (50 entries) but
comments in CLAUDE.md, vector-clocks.md, sync.types.ts, and
validation.service.ts still referenced the old 3x MAX (30) value.
2026-02-10 20:38:32 +01:00
Johannes Millan
13dc7a988a fix(sync): deduplicate retry budget counting per entity per batch
The retry counter incremented per-op instead of per-entity per cycle.
Multiple ops for the same entity in one batch would burn through all
MAX_CONCURRENT_RESOLUTION_ATTEMPTS immediately, causing permanent
rejection on the first sync cycle instead of allowing 3 retry cycles.

Also uses toEntityKey utility instead of manual string construction
and fixes docs/code mismatch (>= vs ===) for pruning-aware comparison.
2026-02-10 14:41:16 +01:00
Johannes Millan
c112b65d64 docs(sync): document pruning artifact heuristic and add rejection counter tests
Document the _isLikelyPruningArtifact() heuristic in vector-clocks.md
and add 3 tests for per-entity rejection counter edge cases.
2026-02-09 17:55:12 +01:00
Johannes Millan
fdc942babb
fix(sync): prevent infinite loop when concurrent modification resolution keeps failing (#6434)
* fix(sync): prevent infinite loop when concurrent modification resolution keeps failing

When vector clock pruning makes it impossible to create a dominating clock
(e.g., entity clock has MAX entries and client ID isn't among them), the cycle
"upload → CONFLICT_CONCURRENT → merge clocks → upload → reject again" repeats
endlessly. This adds a per-entity retry counter (MAX_CONCURRENT_RESOLUTION_ATTEMPTS=3)
that permanently rejects ops after exceeding the limit, breaking the sync loop.

The counter resets when a sync cycle completes with no rejections (healthy state).

https://claude.ai/code/session_016RAxms5dTouU98wFNQaAcv

* fix(sync): move vector clock pruning after conflict detection to fix root cause

The infinite sync loop happens because it's mathematically impossible to build
a dominating clock with MAX_VECTOR_CLOCK_SIZE entries when the entity's clock
already has MAX entries and the client's ID isn't among them. The merged clock
needs MAX+1 entries (all entity clock IDs + client ID), but client-side pruning
drops one entity clock ID. The server's pruning-aware comparison then sees the
dropped key as non-shared and returns CONCURRENT instead of GREATER_THAN.

Fix: Move limitVectorClockSize from validation (before comparison) to
processOperation (after comparison, before storage). The full unpruned clock
is now used for conflict detection — all entity clock IDs are present so
bOnlyCount=0 → GREATER_THAN. Storage still gets the pruned clock.

Client-side: Stop pruning in SupersededOperationResolverService. The server
handles pruning after conflict detection.

https://claude.ai/code/session_016RAxms5dTouU98wFNQaAcv

* fix(sync): tighten vector clock sanitize limit from 100 to 3x MAX_VECTOR_CLOCK_SIZE

The old sanitize cap of 100 entries was unnecessarily wide. Since conflict
resolution clocks are at most ~12-15 entries (entity clock MAX=10 + client ID
+ a few merged), cap at 3x MAX (30) for DoS protection while leaving ample
room for legitimate clocks.

Also update server-side pruning tests to use realistic clock sizes (20 entries
instead of 50) to stay within the new sanitize limit.

https://claude.ai/code/session_016RAxms5dTouU98wFNQaAcv

* docs(sync): document vector clock pruning invariant and infinite loop fix

- Add "Pruning and the Pruning-Aware Comparison" section to vector-clocks.md
  explaining the critical invariant: server prunes AFTER comparison, not before
- Add rule 13 to CLAUDE.md to prevent future regressions
- Update conflict resolution key files table with rejected-ops-handler and
  superseded-operation-resolver services

https://claude.ai/code/session_016RAxms5dTouU98wFNQaAcv

* docs(sync): update last-updated date in conflict resolution docs

https://claude.ai/code/session_016RAxms5dTouU98wFNQaAcv

* test(sync): update pruning tests to reflect server-side pruning design

Client no longer prunes vector clocks during conflict resolution — the
server handles pruning after conflict detection. Tests now verify the
merged clock is sent unpruned with all keys preserved.

https://claude.ai/code/session_016RAxms5dTouU98wFNQaAcv

* test(sync): fix client-side pruning tests and add server-side regression test

- Update 7 SupersededOperationResolverService tests to verify client
  does NOT prune (server handles pruning after conflict detection)
- Remove redundant `newClock` alias in superseded-operation-resolver
- Add regression test: MAX+1 entry clock accepted as GREATER_THAN
  when it dominates a MAX entry entity clock (the core infinite loop fix)

https://claude.ai/code/session_016RAxms5dTouU98wFNQaAcv

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-09 12:01:43 +01:00
Johannes Millan
2a6de0e41f fix(sync): remove dead code, add defensive checks, and clean up vector clock logic
- Remove redundant subset condition in compareVectorClocks
- Add clarifying comment for conservative return in hasVectorClockChanges
- Batch per-key verbose logs into single summary log
- Add defensive warning for negative startingSeq in file-based sync
- Extract magic timeout constant in E2E test
- Update stale doc date
2026-02-02 17:15:13 +01:00
Johannes Millan
192ec62d4a fix(sync): harden vector clock comparison and fix docs
- Replace fragile VectorClockComparison[result] enum lookup with safe cast
- Return CONCURRENT instead of EQUAL when only one side has non-shared
  keys in pruning-aware mode (safe direction: triggers LWW instead of
  silent skip)
- Fix docs claiming clocks "reset" at MAX_SAFE_INTEGER (they throw)
2026-01-30 20:05:48 +01:00
Johannes Millan
495f0fe0d3 fix(sync): improve vector clock pruning awareness and harden tests
Make hasVectorClockChanges pruning-aware by checking clock size before
logging missing keys — downgrade to verbose when pruning is likely,
warn when corruption is likely. Add return value assertion to LWW retry
exhaustion test, asymmetric pruning test cases, server-side pruning
tradeoff documentation, and fix stale "max 50" in docs.
2026-01-30 19:35:51 +01:00
Johannes Millan
361d0e605f refactor(sync): rename "stale" to "superseded" across sync/operation domain
Includes backward compatibility: client accepts both CONFLICT_SUPERSEDED
and CONFLICT_STALE from the server, and the server keeps a deprecated
CONFLICT_STALE alias. Remove after all deployments are updated.
2026-01-30 16:59:40 +01:00
Johannes Millan
4ab86ba0fe docs(sync): document archive-wins rule, singleton LWW, and stale op handling
Document 6 gaps found during documentation audit:

- Archive-wins conflict resolution rule (moveToArchive always wins
  over field-level updates regardless of timestamps)
- Two-level archive resurrection prevention (ConflictResolutionService
  + bulkOperationsMetaReducer pre-scan filtering)
- Singleton entity LWW update handling (adapter vs singleton vs
  unsupported storage patterns)
- Stale moveToArchive operation preservation with merged vector clocks
- Fix upload batch size from 100 to 25 in operation-rules.md and
  operation-log-architecture.md
- Update meta-reducer chain from simplified 7-phase to accurate
  8-phase, 15-entry structure matching meta-reducer-registry.ts
2026-01-30 16:59:40 +01:00
Johannes Millan
e6fba6b3ed docs(sync): document protected client IDs mechanism and update tests
Add documentation explaining why all vectorClock keys must be protected
during SYNC_IMPORT/BACKUP_IMPORT operations to prevent incorrect
CONCURRENT comparisons after vector clock pruning.

Update tests to verify multi-key vectorClock protection.
2026-01-27 18:43:22 +01:00
Johannes Millan
038a722ed8 style: apply prettier formatting 2026-01-10 17:09:14 +01:00
Johannes Millan
9605177fc0 docs: enhance SuperSync vs file-based comparison with detailed diagrams
Add comprehensive comparison diagrams:
- Side-by-side architecture showing upload/download flows
- Key conceptual differences (source of truth, sequencing, etc.)
- Detailed feature comparison table with "winner" column
- Trade-offs visualization (bandwidth, setup, history, etc.)
- Concurrent edit scenario showing gap detection vs piggybacking
2026-01-08 11:31:07 +01:00
Johannes Millan
c7bc9d4978 docs: add detailed master architecture diagram for file-based sync
Replace simple "Complete System Flow" with comprehensive diagram showing:
- Client-side sync loop, download flow, upload flow
- Conflict management with LWW auto-resolution
- First-sync conflict dialog and snapshot hydration
- Piggybacking mechanism on upload
- File provider layer with adapter methods
- Remote storage structure

Also add Quick Reference Tables for:
- File operations (download/upload methods)
- sync-data.json structure
- Key implementation details
2026-01-08 11:12:42 +01:00
Johannes Millan
9f0adbb95c docs: fix outdated file paths and types in diagrams
- Fix FileBasedSyncData type: remove non-existent lastSeq, add clientId
- Fix file paths: op-log/processing → op-log/apply
- Fix file paths: features/time-tracking → features/archive
- Fix file path: super-sync not supersync
- Fix vector-clock path: now in op-log/sync/
- Remove non-existent state-capture.meta-reducer.ts reference
- Remove pfapi-migration.service.ts (no longer exists)

docs: remove outdated .bak file references from diagrams

The backup file (sync-data.json.bak) is no longer created during
upload. It's only deleted as cleanup from legacy implementations.

docs: add sync comparison and simple sync flow diagrams

- Add 07-supersync-vs-file-based.md comparing the two sync approaches
- Add 08-sync-flow-explained.md with step-by-step sync explanation
- Remove consolidated unified-oplog-sync-diagrams.md
- Update diagrams README with new entries

docs(sync): reorganize diagrams into subfolder and update for unified architecture

- Create docs/sync-and-op-log/diagrams/ with topic-based diagram files
- Remove outdated PFAPI Legacy Bridge references from diagrams
- Update archive diagrams to use generic "Archive Database" naming
- Fix file paths from sync/providers/ to sync-providers/
- Update quick-reference Area 12 to show unified file-based sync
- Update README to reference new diagram locations

docs: update architecture docs to reflect PFAPI elimination

- Delete obsolete PFAPI documentation:
  - docs/sync-and-op-log/pfapi-sync-persistence-architecture.md
  - docs/sync-and-op-log/pfapi-sync-overview.md
  - docs/plans/pfapi-elimination-status.md

- Update sync-and-op-log/README.md:
  - Describe unified operation log architecture
  - Document file-based sync (Part B) and server sync (Part C)
  - Update file structure to reflect sync-providers location

- Update operation-log-architecture.md:
  - Rewrite Part B from "Legacy Sync Bridge" to "File-Based Sync"
  - Remove all PFAPI code examples and references
  - Update IndexedDB structure diagram (single SUP_OPS database)
  - Update architecture overview to show current provider structure
  - Add notes about PFAPI elimination (January 2026)

- Mark completed implementation plans:
  - replace-pfapi-with-oplog-plan.md - marked as COMPLETED
  - file-based-oplog-sync-implementation-plan.md - marked as COMPLETED

Also includes fix for file-based sync gap detection to handle
snapshot replacement (when "Use Local" is chosen in conflict resolution).
2026-01-08 11:10:29 +01:00
Johannes Millan
4e49628eca chore: clean up leftover pfapi references after refactor
- Remove dead test:shard:pfapi script from package.json
- Update AGENTS.md persistence layer path to op-log and sync
- Update documentation file paths in secure-storage.md,
  vector-clocks.md, and quick-reference.md
2026-01-07 21:10:38 +01:00
Johannes Millan
1f8fe61c84 refactor: integrate pfapi into oplog 1 2026-01-07 13:30:09 +01:00
Johannes Millan
936f374bde refactor(sync): address code review findings for operation log
Phase 1 - Fix archive circular dependency:
- Create ArchiveDbAdapter for direct IndexedDB access to archive data
- Update ArchiveOperationHandler to use ArchiveDbAdapter instead of
  lazy-injecting PfapiService, breaking the circular dependency chain
- Update tests to mock ArchiveDbAdapter

Phase 2 - Address testing gaps:
- Add 3 timeout exhaustion tests for compaction service (25s timeout)
- Add 5 clock skew edge case tests for conflict resolution:
  - Far future/past timestamps
  - Zero and negative timestamps
  - Client ID tie-breaker for identical timestamps

Phase 3 - Document cross-version migration (A.7.11):
- Add comprehensive implementation guide in architecture doc covering:
  - When to bump CURRENT_SCHEMA_VERSION
  - Operation transformation strategy
  - Conflict detection across versions
  - Backward compatibility guarantees
  - Migration rollout strategy
  - Example migration and testing requirements

All 1399 op-log tests pass.
2026-01-02 13:48:22 +01:00
Johannes Millan
c29913aeac test(time-tracking): add comprehensive tests and documentation
Add extensive tests and documentation for TimeTrackingState sync:

Unit tests (~22 new):
- merge-time-tracking-states.spec.ts: partial data merging, null
  handling, merge priority, scale testing
- sort-data-to-flush.spec.ts: flush completeness, LWW behavior,
  date boundaries
- time-tracking.reducer.spec.ts: context preservation, immutability

Integration tests (9 new):
- time-tracking-sync.integration.spec.ts: operation creation,
  SYNC_IMPORT with timeTracking, multi-client sync, archive flush

Server tests (18 new):
- time-tracking-operations.spec.ts: operation upload, conflict
  detection, snapshot generation, LWW semantics

Documentation:
- JSDoc for merge-time-tracking-states.ts and sort-data-to-flush.ts
- Section E.6 "Time Tracking Sync Semantics" in architecture docs
2025-12-28 13:16:07 +01:00
Johannes Millan
d6dcc86ca0 refactor: reorganize operation-log files into src/app/op-log/
Move operation-log from src/app/core/persistence/operation-log/ to
src/app/op-log/ with improved subdirectory organization:

- core/: Types, constants, errors, entity registry
- capture/: Write path (Actions → Operations)
  - operation-capture.meta-reducer.ts
  - operation-capture.service.ts
  - operation-log.effects.ts
- apply/: Read path (Operations → State)
  - bulk-hydration.action.ts/.meta-reducer.ts
  - operation-applier.service.ts
  - operation-converter.util.ts
  - hydration-state.service.ts
  - archive-operation-handler.service.ts/.effects.ts
- store/: IndexedDB persistence
  - operation-log-store.service.ts
  - operation-log-hydrator.service.ts
  - operation-log-compaction.service.ts
  - schema-migration.service.ts
- sync/: Server sync (SuperSync)
  - operation-log-sync.service.ts
  - operation-log-upload.service.ts
  - operation-log-download.service.ts
  - conflict-resolution.service.ts
  - sync-import-filter.service.ts
  - vector-clock.service.ts
  - operation-encryption.service.ts
- validation/: State validation
  - validate-state.service.ts
  - validate-operation-payload.ts
- util/: Shared utilities
  - entity-key.util.ts
  - client-id.provider.ts
- testing/: Integration tests and benchmarks

This reorganization:
- Places op-log at the same level as pfapi for better visibility
- Groups files by responsibility (write path vs read path)
- Makes the sync architecture more discoverable
- Improves navigation for developers new to the codebase
2025-12-27 17:52:11 +01:00
Johannes Millan
693e71deeb docs(sync): complete quick-reference with Areas 8-12
Add visual summaries for remaining areas:
- Area 8: Meta-Reducers (atomic multi-entity changes)
- Area 9: Compaction (snapshot + garbage collection)
- Area 10: Bulk Application (single dispatch optimization)
- Area 11: Encryption (AES-256-GCM + Argon2id)
- Area 12: Legacy PFAPI Bridge (WebDAV/Dropbox)

Removes "Coming Soon" placeholder. All 12 areas now documented.
2025-12-27 17:10:18 +01:00
Johannes Millan
e221afe81c docs(sync): add quick-reference.md with visual summaries
Create a quick reference document with ASCII diagrams summarizing:
- Area 1: Write Path
- Area 2: Read Path (Hydration)
- Area 3: Server Sync (SuperSync)
- Area 4: Conflict Detection
- Area 5: Conflict Resolution (LWW)
- Area 6: SYNC_IMPORT Filtering
- Area 7: Archive Handling

Includes decision tables, key invariants, and file references.
Areas 8-12 placeholders for future additions.
2025-12-27 16:42:38 +01:00
Johannes Millan
330ecce2c9 docs(sync): fix LWW timestamp and SYNC_IMPORT filtering sections
- C.5: Correct "Current timestamp" to "Preserved maximum timestamp
  from local ops" - critical for correct LWW semantics
- C.7: Rewrite "Late-Joiner Replay" as "SYNC_IMPORT Filtering" to
  reflect actual "Clean Slate Semantics" implementation:
  - CONCURRENT ops are now DROPPED, not replayed
  - Uses SyncImportFilterService, not removed _replayLocalSyncedOpsAfterImport()
  - Vector clock comparison determines causality, not UUIDv7 timestamps
2025-12-27 15:59:00 +01:00
Johannes Millan
8fff1325b4 docs: fix SYNC_IMPORT filtering section to match implementation
- Fix CLAUDE.md path reference from docs/op-log/ to docs/sync-and-op-log/
- Rewrite section 2c in architecture diagrams to reflect actual implementation:
  - Was: UUIDv7 timestamp replay (removed feature)
  - Now: Vector clock filtering with clean slate semantics
- Update service reference from removed _replayLocalSyncedOpsAfterImport()
  to SyncImportFilterService.filterOpsInvalidatedBySyncImport()
- Clarify that CONCURRENT ops are dropped, not replayed
2025-12-27 13:15:47 +01:00
Johannes Millan
c1575d7669 docs(sync): update operation-log docs to reflect current implementation
- Update README.md with correct links and implementation status
- Add E2EE to implementation status (now complete)
- Update e2e-encryption-plan.md to mark as implemented
- Update operation-log-architecture.md:
  - Add missing service files to file reference section
  - Add E2EE to Part C and "Recently Completed" sections
  - Fix broken references, update last modified date
- Remove reference to non-existent tiered-archive-proposal.md
2025-12-27 11:44:30 +01:00
Johannes Millan
39d6e15446 docs: improve structure 2025-12-27 11:32:54 +01:00
Johannes Millan
7227749ec4 test(sync): add tests for bulk dispatch edge cases
Add comprehensive tests for operation applier testing gaps:

- Partial archive failure: verifies that when archive handling fails
  midway through a batch, previously processed ops are reported
  as successful while remaining ops are not applied
- Effects isolation: confirms that only bulkApplyOperations action
  is dispatched (not individual action types), which is the key
  architectural benefit preventing effects from firing on remote ops
- Multiple archive-affecting ops: ensures remoteArchiveDataApplied
  is dispatched exactly once when batch contains multiple
  archive-affecting operations

Total: 4 new test cases, 24 tests now passing
2025-12-27 11:31:51 +01:00