mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-09-03 17:27:06 +00:00
Merge pull request #1159 from vrtmrz/docs/replicator-architecture
Document the implemented Replicator architecture
This commit is contained in:
@@ -5,10 +5,11 @@ When working on this repository (writing code, comments, documentation, or commi
|
||||
## Required Reference Files
|
||||
|
||||
Before making changes to documentation, user-facing text, or settings:
|
||||
1. Read [docs/terms.md](docs/terms.md) for terminology, vocabulary conventions, and technical definitions.
|
||||
2. Read [docs/settings.md](docs/settings.md) (and [docs/settings_ja.md](docs/settings_ja.md)) for UI settings and setting key mappings.
|
||||
3. Read [docs/troubleshooting.md](docs/troubleshooting.md) for troubleshooting guidelines and common recovery steps (such as flag files and SCRAM state).
|
||||
4. Read [devs.md](devs.md) for development workflows, module architecture, and testing infrastructure.
|
||||
1. Read [docs/terms.md](docs/terms.md) for documentation style and vocabulary conventions.
|
||||
2. Read [docs/glossary.md](docs/glossary.md) for user-facing, operational, developer, and design terminology.
|
||||
3. Read [docs/settings.md](docs/settings.md) (and [docs/settings_ja.md](docs/settings_ja.md)) for UI settings and setting key mappings.
|
||||
4. Read [docs/troubleshooting.md](docs/troubleshooting.md) for troubleshooting guidelines and common recovery steps (such as flag files and SCRAM state).
|
||||
5. Read [devs.md](devs.md) for development workflows, module architecture, and testing infrastructure.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+4
-1
@@ -57,7 +57,10 @@ To maintain consistency across the project, we ask that you follow the establish
|
||||
- **Affirmative Phrasing**: Avoid asking questions using negative forms in user-facing dialogue. Use affirmative questions to prevent translation and interpretation discrepancies.
|
||||
- **Specific Words**: Use 'dialogue' for documentation and user-facing messages (use 'dialog' only inside source code). Use the hyphenated form 'plug-in' in user-facing text (use 'plugin' only in configuration settings or technical contexts).
|
||||
|
||||
For a detailed list of vocabulary conventions and terms, please refer to [docs/terms.md](docs/terms.md).
|
||||
For writing conventions, see [Documentation style and vocabulary conventions](docs/terms.md).
|
||||
Project-specific meanings are defined in the [Project glossary](docs/glossary.md),
|
||||
including internal developer and design terms which might not appear in the
|
||||
user interface.
|
||||
|
||||
### 3. Translations
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ To facilitate development and testing, the build process can automatically copy
|
||||
|
||||
Regression tests remain in the suite owned by the implementation under test. Plug-in tests may be co-located with their source, while independent application tests remain under `test/apps/` or `test/browser-apps/` so that they stay outside the Community Review source boundary. Prefix a case or group with `compatibility:` when it protects a persisted input or state which current releases still accept, and with `retirement guard:` when it prevents a removed setting, control, or notification from returning. Remove or replace a compatibility case only when the corresponding input is no longer accepted or an equivalent maintained case preserves the contract. Remove a retirement guard only when another current contract makes the old behaviour unreachable. Do not preserve a disconnected historical test as an executable specification when no maintained runner invokes it; Git history is the reference for retired test infrastructure.
|
||||
|
||||
- **CLI E2E** (`src/apps/cli/testdeno/`): Host-independent consumer workflows. The canonical Compose P2P suite covers ordinary two-peer synchronisation, replacement of the current replicator followed by transfer with the same peer, and explicit relay disconnection followed by paused and resumed reconnection. Its lifecycle entry point is included only in the Docker test build and does not add a public CLI command. Run `npm run test:e2e:cli` for the ordinary suite or `npm run test:e2e:cli:p2p` for P2P validation.
|
||||
- **CLI E2E** (`src/apps/cli/testdeno/`): Host-independent consumer workflows. The canonical Compose P2P suite covers ordinary two-peer synchronisation, replacement of the current Replicator followed by transfer with the same peer, and explicit relay disconnection followed by paused and resumed reconnection. Its lifecycle entry point is included only in the Docker test build and does not add a public CLI command. Run `npm run test:e2e:cli` for the ordinary suite or `npm run test:e2e:cli:p2p` for P2P validation.
|
||||
- **Self-hosted setup tools** (`utils/couchdb/`, `utils/setup/`, and `utils/flyio/`): Deno contract tests consume the exact locked Commonlib registry package, verify current CouchDB, Object Storage, and random-room P2P Setup URI defaults and remote profiles, and keep CouchDB administration separate from package-owned LiveSync database-version negotiation. `unit-ci` also provisions a real temporary CouchDB database and verifies its version document against the installed Commonlib package. Run `npm run test:setup-tools` for the local contract gate.
|
||||
- **Real Obsidian E2E** (`test/e2e-obsidian/`): Local-first scripts that launch real Obsidian with temporary vaults and the built Self-hosted LiveSync plug-in. Use these for boot-up sequence, vault reflection, RedFlag flows, Fast Setup (Simple Fetch), settings dialogues, restart-sensitive workflows, Object Storage regressions, and other behaviour that depends on Obsidian itself. Run focused scripts such as `npm run test:e2e:obsidian:two-vault-sync`, or use `npm run test:e2e:obsidian:local-suite:services` to run the broader local suite with CouchDB and MinIO fixtures managed by the wrapper.
|
||||
|
||||
@@ -129,6 +129,10 @@ Changes spanning both repositories must first produce a packed Commonlib artefac
|
||||
|
||||
## Architecture
|
||||
|
||||
The [Project glossary](docs/glossary.md#developer-and-design-terms) defines the
|
||||
stable developer and design vocabulary used in this section. The guidance
|
||||
below describes how those boundaries are applied.
|
||||
|
||||
### Service composition and legacy Modules
|
||||
|
||||
The application is composed from Services, ServiceModules, serviceFeatures, add-ons, and a legacy Module layer:
|
||||
@@ -138,7 +142,7 @@ The application is composed from Services, ServiceModules, serviceFeatures, add-
|
||||
- **serviceFeature**: a typed composition function which accepts only its declared Services and ServiceModules. It registers lifecycle handlers, commands, user-interface bindings, or other host glue, and may return a focused view. It is not a runtime registry entry.
|
||||
- **AbstractModule** and **AbstractObsidianModule**: the legacy application Module layer. Existing Modules are loaded by the application and bound after the Service graph has been composed; this broad core access is not the preferred dependency boundary for new orchestration.
|
||||
|
||||
The normal composition order is the Service Hub, replicator-provider registration, ServiceModules, serviceFeatures, add-ons, and finally legacy Module binding. A serviceFeature may therefore consume an already constructed ServiceModule. Preferring a serviceFeature for new composition is a dependency-boundary rule, not an initialisation-order rule.
|
||||
The normal composition order is the Service Hub, Replicator provider registration, ServiceModules, serviceFeatures, add-ons, and finally legacy Module binding. A serviceFeature may therefore consume an already constructed ServiceModule. Preferring a serviceFeature for new composition is a dependency-boundary rule, not an initialisation-order rule.
|
||||
|
||||
Mutable state is permitted in a serviceFeature. State alone is not a reason to create a class, a ServiceModule, or retain an AbstractModule. Prefer one private context, with module-level functions which receive that context, when identity and polymorphism are not part of the contract. Separate the state, transitions, and invariants from the surrounding function which registers lifecycle handlers and connects downstream effects. Give the stateful boundary narrow collaborators rather than `LiveSyncBaseCore`.
|
||||
|
||||
@@ -169,7 +173,12 @@ Legacy Modules remain grouped by directory:
|
||||
- **Service Hub** (`src/modules/services/`): Central service registry using dependency injection
|
||||
- **Common Library** (`@vrtmrz/livesync-commonlib`): Platform-independent synchronisation logic, shared with the CLI, WebApp, WebPeer, and external tools
|
||||
|
||||
Commonlib owns one stable `LiveSyncP2PService`, its `P2PRoomSessionOwner`, and the replaceable Trystero room session. Host commands, event handlers, and views consume the focused transport, connection-probe admission, directory, peer-admission, transfer, change-relay, configuration, and diagnostic views returned by the service feature. They must not retain the deprecated compatibility Replicator as an ordinary service locator, close Trystero-owned raw peers, or install another Trystero transport generation at the application root. The exact as-built ownership and shutdown boundaries are recorded in Commonlib's `docs/p2p-transport-lifecycle.md` design document.
|
||||
See [Replicator architecture](docs/design_docs/replicator_architecture.md) for
|
||||
the implemented provider contract, active Replicator lifecycle, publication and
|
||||
session fences, P2P ownership exception, compatibility boundaries, and the
|
||||
steps required to add a built-in provider.
|
||||
|
||||
Commonlib owns one stable `LiveSyncP2PService`, its `P2PRoomSessionOwner`, and the replaceable Trystero room session. Host commands, event handlers, and views consume the focused transport, connection-probe admission, directory, peer-admission, transfer, change-relay, configuration, and diagnostic views returned by the service feature. They must not retain the deprecated compatibility Replicator as an ordinary service locator, close Trystero-owned raw peers, or install another Trystero transport generation at the application root. The exact implemented ownership and shutdown boundaries are recorded in Commonlib's [P2P transport lifecycle](https://github.com/vrtmrz/livesync-commonlib/blob/main/docs/p2p-transport-lifecycle.md) design document.
|
||||
|
||||
### Conflict Merge Policy
|
||||
|
||||
@@ -254,7 +263,7 @@ Existing legacy Modules continue to register their handlers in `onBindFunction()
|
||||
`Plugin.addSettingTab()`. Register a settings tab which reads persisted values
|
||||
from the sequential `onSettingLoaded` lifecycle, seed its editing snapshot
|
||||
before registration, and keep definition construction independent of local
|
||||
database and replicator readiness. See
|
||||
database and Replicator readiness. See
|
||||
[the declarative settings adapter ADR](docs/adr/2026_08_declarative_settings_adapter.md).
|
||||
- Use `this.services.setting.saveSettingData()` instead of using plugin methods directly
|
||||
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
---
|
||||
date: 2026-09-03
|
||||
commonlib-version: "0.1.21"
|
||||
self-hosted-livesync-version: "1.0.24"
|
||||
status: accepted
|
||||
---
|
||||
|
||||
# Architectural Decision Record: P2P Room and Transport Lifecycle
|
||||
|
||||
## Status
|
||||
|
||||
Accepted — implemented and verified through Commonlib owner tests, the Compose transport suite, and the real-Obsidian setup workflow.
|
||||
|
||||
The stable P2P service and room-session owner accepted in
|
||||
[Replicator Capabilities and Lifecycle Orchestration — Part 2](2026_08_replicator_capabilities_02_p2p_service_lifecycle.md)
|
||||
supersede only this record's replaceable LiveSync P2P Replicator and ownership
|
||||
of the replaceable result returned by the `serviceFeature`. This record remains
|
||||
authoritative for serialised room operations, `room.leave()`, Trystero-owned
|
||||
physical peers, and relay reconnection.
|
||||
|
||||
## Context
|
||||
|
||||
Self-hosted LiveSync uses Trystero's Nostr strategy for P2P discovery, signalling, and WebRTC transport. Three related resources have different owners and lifetimes:
|
||||
@@ -12,7 +26,7 @@ Self-hosted LiveSync uses Trystero's Nostr strategy for P2P discovery, signallin
|
||||
- Trystero owns the underlying WebRTC peers and may share one physical peer across more than one room; and
|
||||
- Trystero's Nostr relay manager owns WebSocket clients shared by relay URL.
|
||||
|
||||
Closing every `RTCPeerConnection` returned by `room.getPeers()` bypasses Trystero's shared-peer manager. The manager may then retain a stale shared peer and prevent a replacement LiveSync replicator from discovering the same remote peer again.
|
||||
Closing every `RTCPeerConnection` returned by `room.getPeers()` bypasses Trystero's shared-peer manager. The manager may then retain a stale shared peer and prevent a replacement LiveSync Replicator from discovering the same remote peer again.
|
||||
|
||||
Room departure and physical transport destruction are not equivalent. `room.leave()` sends the room-leave action, removes that room's actions and callbacks, and detaches its shared-peer binding. Trystero may retain a healthy physical WebRTC peer for later reuse after the last room binding has gone. The retained peer cannot carry actions for the room which has been left.
|
||||
|
||||
@@ -40,7 +54,7 @@ The explicit disconnect operation therefore has the following contract:
|
||||
|
||||
This operation is a logical LiveSync disconnection and a physical signalling-server disconnection. It does not promise that every browser-owned WebRTC object has been destroyed synchronously.
|
||||
|
||||
An explicit connect resumes relay reconnection before opening a new room. Settings application and database lifecycle replacement close the current LiveSync replicator, discard it, construct a new instance from the current settings, and open that current instance when the configured policy requires it. Commands, event handlers, and panes resolve the current service-feature result at the point of use rather than retaining an obsolete replicator.
|
||||
An explicit connect resumes relay reconnection before opening a new room. Settings application and database lifecycle replacement close the current LiveSync Replicator, discard it, construct a new instance from the current settings, and open that current instance when the configured policy requires it. Commands, event handlers, and panes resolve the focused views returned by the current P2P `serviceFeature` at the point of use rather than retaining an obsolete Replicator.
|
||||
|
||||
Lifecycle operations on one `LiveSyncTrysteroReplicator` are serialised. A close requested while an open is in progress must leave no orphan room serving, and repeated opens must not create parallel rooms. No fixed delay is inserted between close and open: readiness is determined by the actual lifecycle operation and peer discovery.
|
||||
|
||||
@@ -50,7 +64,7 @@ P2P setup follows the transport's actual ownership model. Initialising the first
|
||||
|
||||
## Ownership
|
||||
|
||||
Commonlib owns the LiveSync-specific P2P service, RPC, command, and lifecycle composition. Trystero owns WebRTC peer creation, sharing, reuse, stale detection, and destruction, as well as relay-client reconstruction. The Self-hosted LiveSync host owns the current Commonlib service-feature result and supplies the platform services used by its current replicator.
|
||||
Commonlib owns the LiveSync-specific P2P service, RPC, command, and lifecycle composition. Trystero owns WebRTC peer creation, sharing, reuse, stale detection, and destruction, as well as relay-client reconstruction. The Self-hosted LiveSync host owns the focused views returned by the current Commonlib P2P `serviceFeature` and supplies the platform services used by its current Replicator.
|
||||
|
||||
Self-hosted LiveSync does not add a separate root Trystero dependency. Tests which must observe relay sockets resolve the exact Trystero generation owned by the locked Commonlib package, avoiding two independent transport singletons in one process.
|
||||
|
||||
@@ -58,7 +72,7 @@ Self-hosted LiveSync does not add a separate root Trystero dependency. Tests whi
|
||||
|
||||
### Close every value returned by `room.getPeers()`
|
||||
|
||||
This bypasses Trystero's shared-peer manager and can prevent a replacement replicator from rediscovering the same peer.
|
||||
This bypasses Trystero's shared-peer manager and can prevent a replacement Replicator from rediscovering the same peer.
|
||||
|
||||
### Add a fixed close-to-open delay
|
||||
|
||||
@@ -76,15 +90,15 @@ This interferes with Trystero's shared relay clients. The public pause and resum
|
||||
|
||||
Commonlib unit tests prove that normal P2P host closure calls `room.leave()` without directly closing Trystero-owned peer connections. Additional package tests cover the action API, replaceable peer-event subscriptions, multiple RPC transport disposers, serialised open and close operations, initialisation of the first device without a central remote, and Fetch running once for an additional device.
|
||||
|
||||
Self-hosted LiveSync unit tests prove that settings and database replacement leave panes on the current replicator, and that an explicit P2P rebuild bypasses the policy intended for ordinary replication.
|
||||
Self-hosted LiveSync unit tests prove that settings and database replacement leave panes on the current Replicator, and that an explicit P2P rebuild bypasses the policy intended for ordinary replication.
|
||||
|
||||
The canonical Compose P2P suite uses a real local Nostr relay and WebRTC implementation. It covers ordinary two-peer synchronisation, replacement of the active LiveSync replicator followed by discovery and transfer with the same peer, and explicit relay disconnection followed by paused and resumed reconnection. The lifecycle scenario is exposed only through a Docker test build and an injected CLI command runner; it is not part of the public CLI command surface.
|
||||
The canonical Compose P2P suite uses a real local Nostr relay and WebRTC implementation. It covers ordinary two-peer synchronisation, replacement of the active LiveSync Replicator followed by discovery and transfer with the same peer, and explicit relay disconnection followed by paused and resumed reconnection. The lifecycle scenario is exposed only through a Docker test build and an injected CLI command runner; it is not part of the public CLI command surface.
|
||||
|
||||
The real-Obsidian P2P Setup URI workflow creates the first device, generates the second-device URI from it, accepts each peer visibly, and verifies a two-way note round-trip through a local relay. A separate focused pane test covers the principal connection control and teardown without requiring a remote peer. Transport replacement and relay-socket lifecycle remain owned by the package and Compose tests rather than being duplicated in Obsidian.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Replacing a P2P replicator no longer leaves host views or commands bound to an obsolete instance.
|
||||
- Replacing a P2P Replicator no longer leaves host views or commands bound to an obsolete instance.
|
||||
- Explicit signalling-server disconnection has a testable socket-level meaning without claiming immediate destruction of idle WebRTC objects.
|
||||
- Settings which change the relay, room, passphrase, or TURN configuration can replace the whole LiveSync room safely.
|
||||
- Trystero may reuse healthy peers across room lifecycles, reducing unnecessary renegotiation.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
date: 2026-08-27
|
||||
commonlib-version: "0.1.20"
|
||||
self-hosted-livesync-version: "1.0.21"
|
||||
status: proposed
|
||||
date: 2026-09-02
|
||||
commonlib-version: "0.1.21"
|
||||
self-hosted-livesync-version: "1.0.23"
|
||||
status: accepted
|
||||
series: replicator-capabilities-and-lifecycle
|
||||
part: 1 of 3
|
||||
---
|
||||
@@ -15,15 +15,20 @@ then [Part 3: migration plan and verification](2026_08_replicator_capabilities_0
|
||||
|
||||
## Status
|
||||
|
||||
Proposed. This record defines the provider, capability, lifecycle, interaction,
|
||||
Accepted and implemented in Commonlib 0.1.21 and Self-hosted LiveSync 1.0.23.
|
||||
This record defines the provider, capability, lifecycle, interaction,
|
||||
ownership, and probe boundaries required by current Self-hosted LiveSync
|
||||
consumers. It is the generic part of the series; the P2P-specific ownership
|
||||
rules live in Part 2, and implementation sequencing lives in Part 3.
|
||||
rules live in Part 2, and the completed implementation sequence lives in Part
|
||||
3. The current structure is summarised in the
|
||||
[Replicator architecture](../design_docs/replicator_architecture.md) design
|
||||
document.
|
||||
|
||||
The accepted P2P room and transport lifecycle record remains authoritative for
|
||||
the current P2P implementation until Stage 3 in Part 3 is complete. The
|
||||
supersession boundary for that record is stated in Part 2 and is not repeated
|
||||
here.
|
||||
Stage 3 in Part 3 is complete. The stable P2P service and room-session owner in
|
||||
Part 2 supersede the replaceable LiveSync P2P Replicator ownership described by
|
||||
the earlier P2P room and transport lifecycle record. That accepted record
|
||||
remains authoritative for its retained Trystero room, physical-peer, and relay
|
||||
ownership decisions.
|
||||
|
||||
## Context
|
||||
|
||||
@@ -235,12 +240,14 @@ supplies an exhaustive definition table for that set. The current catalogue is
|
||||
CouchDB, Object Storage, and P2P; it is not a public third-party registration
|
||||
API.
|
||||
|
||||
CouchDB is part of every current host composition. Object Storage and P2P are
|
||||
compile-time composition choices and may be included or omitted without
|
||||
changing the generic scheduling feature. Adding another current provider
|
||||
requires a Commonlib kind and support declaration, host composition,
|
||||
Setup/profile schema handling, and provider-specific tests. It does not require
|
||||
a runtime plug-in registry or behaviour for unknown provider kinds.
|
||||
Every current `LiveSyncBaseCore` host composes CouchDB and Object Storage.
|
||||
`WebPeerRuntime` is a separate P2P-only host composition, and P2P remains a
|
||||
compile-time feature choice for the other hosts. A host can include or omit a
|
||||
provider without changing the generic scheduling feature. Adding another
|
||||
current provider requires a Commonlib kind and support declaration, host
|
||||
composition, Setup/profile schema handling, and provider-specific tests. It
|
||||
does not require a runtime plug-in registry or behaviour for unknown provider
|
||||
kinds.
|
||||
|
||||
Each provider definition supplies:
|
||||
|
||||
@@ -777,6 +784,7 @@ when every caller proves it to be the operation's identity.
|
||||
|
||||
## References
|
||||
|
||||
- [Project glossary](../glossary.md#developer-and-design-terms)
|
||||
- [Part 2: P2P service and session lifecycle](2026_08_replicator_capabilities_02_p2p_service_lifecycle.md)
|
||||
- [Part 3: migration plan and verification](2026_08_replicator_capabilities_03_migration_plan.md)
|
||||
- [Bounded Remote Activity](2026_07_bounded_remote_activity.md)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
date: 2026-08-27
|
||||
commonlib-version: "0.1.20"
|
||||
self-hosted-livesync-version: "1.0.21"
|
||||
status: proposed
|
||||
date: 2026-09-02
|
||||
commonlib-version: "0.1.21"
|
||||
self-hosted-livesync-version: "1.0.23"
|
||||
status: accepted
|
||||
series: replicator-capabilities-and-lifecycle
|
||||
part: 2 of 3
|
||||
---
|
||||
@@ -14,20 +14,24 @@ first, then continue with [Part 3: migration plan and verification](2026_08_repl
|
||||
|
||||
## Status
|
||||
|
||||
Proposed. This record defines the P2P service owner, room-session boundary,
|
||||
narrow contract views, automation demands, replacement fencing, and trigger
|
||||
Accepted and implemented in Commonlib 0.1.21 and Self-hosted LiveSync 1.0.23.
|
||||
This record defines the P2P service owner, room-session boundary, narrow
|
||||
contract views, automation demands, replacement fencing, and trigger
|
||||
semantics. Generic provider and capability rules are owned by Part 1; the
|
||||
implementation and verification order is owned by Part 3.
|
||||
completed implementation and verification order is recorded in Part 3.
|
||||
|
||||
The implemented state is recorded separately in Commonlib's
|
||||
`docs/p2p-transport-lifecycle.md` design document. It supersedes the
|
||||
replaceable LiveSync P2P Replicator and current-result ownership described by
|
||||
[P2P transport lifecycle](https://github.com/vrtmrz/livesync-commonlib/blob/main/docs/p2p-transport-lifecycle.md)
|
||||
design document and summarised with the generic provider lifecycle in the
|
||||
[Replicator architecture](../design_docs/replicator_architecture.md) design
|
||||
document. It supersedes the replaceable LiveSync P2P Replicator and ownership
|
||||
of the replaceable result returned by the `serviceFeature`, as described by
|
||||
the accepted [P2P Room and Transport Lifecycle](2026_07_p2p_transport_lifecycle.md)
|
||||
record. The accepted record's decisions about serialised room operations,
|
||||
record.
|
||||
The accepted record's decisions about serialised room operations,
|
||||
`room.leave()`, Trystero-owned physical peers, and relay reconnection remain in
|
||||
force. This ADR remains the decision and migration target; the Commonlib
|
||||
design document records the names and ownership boundaries which actually
|
||||
landed.
|
||||
force. This ADR records the product decision; the Commonlib design document
|
||||
records the implemented names and ownership boundaries.
|
||||
|
||||
## Scope and context
|
||||
|
||||
@@ -397,6 +401,7 @@ and does not publish a second P2P lifecycle owner.
|
||||
|
||||
## References
|
||||
|
||||
- [Project glossary](../glossary.md#developer-and-design-terms)
|
||||
- [Part 1: core contract](2026_08_replicator_capabilities_01_core_contract.md)
|
||||
- [Part 3: migration plan and verification](2026_08_replicator_capabilities_03_migration_plan.md)
|
||||
- [P2P Room and Transport Lifecycle](2026_07_p2p_transport_lifecycle.md)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
date: 2026-08-27
|
||||
commonlib-version: "0.1.20"
|
||||
self-hosted-livesync-version: "1.0.21"
|
||||
status: proposed
|
||||
date: 2026-09-02
|
||||
commonlib-version: "0.1.21"
|
||||
self-hosted-livesync-version: "1.0.23"
|
||||
status: accepted
|
||||
series: replicator-capabilities-and-lifecycle
|
||||
part: 3 of 3
|
||||
---
|
||||
@@ -16,11 +16,14 @@ another runtime contract.
|
||||
|
||||
## Status
|
||||
|
||||
Proposed. The stages below are an implementation and verification order, not
|
||||
independently releasable states. Commonlib and Self-hosted LiveSync must not
|
||||
publish temporary support boundaries described by an incomplete stage. A
|
||||
release follows only after the target matrix, ownership boundaries, and the
|
||||
contracted production-consumer migrations in Parts 1 and 2 are complete.
|
||||
Accepted and implemented in Commonlib 0.1.21 and Self-hosted LiveSync 1.0.23.
|
||||
The stages below record the implementation and verification order; they were
|
||||
not independently releasable states. The target matrix, ownership boundaries,
|
||||
and contracted production-consumer migrations in Parts 1 and 2 are complete.
|
||||
Items which Stage 7 explicitly defers remain separate compatibility work rather
|
||||
than incomplete stages. The current result is summarised in the
|
||||
[Replicator architecture](../design_docs/replicator_architecture.md) design
|
||||
document.
|
||||
|
||||
## Migration rules
|
||||
|
||||
@@ -103,11 +106,11 @@ until every remaining demand has settled. The LiveSync feature-binding test
|
||||
must not rely on the current registration order of equal-priority resume
|
||||
handlers.
|
||||
|
||||
Until Stage 4 supplies target-aware unattended P2P, each host composition
|
||||
declares generic `P2P_SyncOnReplication` as `not-implemented`. Its automatic
|
||||
request settles without UI with an explicit blocked result. Existing AutoSync,
|
||||
AutoWatch, and accepted incoming-request paths continue with the Stage 2 gate.
|
||||
This is a temporary migration state, not the target matrix in Part 1.
|
||||
Before Stage 4 supplied target-aware unattended P2P, each host composition
|
||||
declared generic `P2P_SyncOnReplication` as `not-implemented`. Its automatic
|
||||
request settled without UI with an explicit blocked result. Existing AutoSync,
|
||||
AutoWatch, and accepted incoming-request paths continued with the Stage 2 gate.
|
||||
This was a temporary migration state, not the target matrix in Part 1.
|
||||
|
||||
Apply and test the CLI scheduling precedence defined in Part 1, so the daemon
|
||||
and scheduling context cannot schedule duplicate initial or recurring work.
|
||||
@@ -178,10 +181,11 @@ Add ownership regressions immediately before implementation:
|
||||
publishing the new database identity, while a failed candidate leaves one
|
||||
observable disconnected state without reviving the fenced session.
|
||||
|
||||
When this stage lands, add a supersession note to the accepted P2P lifecycle
|
||||
record and update `devs.md` from the replaceable concrete Replicator getter to
|
||||
the stable contract views. Preserve the accepted Trystero peer and relay
|
||||
ownership rules rather than rewriting their historical verification.
|
||||
Completion of this stage added a bounded supersession note to the accepted P2P
|
||||
lifecycle record and updated `devs.md` from the replaceable concrete Replicator
|
||||
getter to the stable contract views. The accepted Trystero peer and relay
|
||||
ownership rules remain in force rather than being rewritten as part of this
|
||||
migration.
|
||||
|
||||
## Stage 4: add target-aware unattended P2P orchestration
|
||||
|
||||
@@ -203,14 +207,17 @@ shared-pane synchronisation.
|
||||
Keep the detailed wait, session-demand, de-duplication, and session-epoch state
|
||||
machine in Part 2 rather than expanding the generic provider contract. If
|
||||
implementation evidence requires a refinement, amend Part 2 before completing
|
||||
this stage. After Stage 3 is complete, Part 2 supersedes the
|
||||
replaceable-Replicator and current-result ownership portions of the accepted
|
||||
July 2026 record; its Trystero peer and relay decisions remain unchanged.
|
||||
this stage. With Stage 3 complete, Part 2 supersedes the portions of the
|
||||
accepted July 2026 record concerning the replaceable Replicator and ownership
|
||||
of the replaceable result returned by the `serviceFeature`. Its Trystero peer
|
||||
and relay decisions remain unchanged.
|
||||
|
||||
Commonlib's `docs/p2p-transport-lifecycle.md` design document records the
|
||||
implemented Stage 3 and Stage 4 ownership, demand, automation, replacement,
|
||||
and shutdown behaviour. This document remains the migration and verification
|
||||
sequence rather than a second description of the implemented state.
|
||||
Commonlib's
|
||||
[P2P transport lifecycle](https://github.com/vrtmrz/livesync-commonlib/blob/main/docs/p2p-transport-lifecycle.md)
|
||||
design document records the implemented Stage 3 and Stage 4 ownership, demand,
|
||||
automation, replacement, and shutdown behaviour. This document remains the
|
||||
migration and verification sequence rather than a second description of the
|
||||
implemented state.
|
||||
|
||||
## Stage 5: separate active construction and flow-specific probes
|
||||
|
||||
@@ -231,8 +238,8 @@ making active construction private.
|
||||
The provider-defined active-construction path is now private to
|
||||
`ReplicatorService`. The public `getNewReplicator` handler remains as a
|
||||
compatibility surface, but current Self-hosted LiveSync production code no
|
||||
longer calls it. Its removal belongs to Stage 7 after any external compatibility
|
||||
decision has been made.
|
||||
longer calls it. Stage 7 reviewed its possible removal and deferred it pending
|
||||
an external compatibility decision.
|
||||
|
||||
The current host composition has migrated CouchDB and Object Storage connection
|
||||
checks, passphrase inspection, preferred-tweak reads, CLI remote status and
|
||||
@@ -246,10 +253,11 @@ against the active relay binding held by the stable P2P service. The Stage 7
|
||||
review identified and completed that remaining owner boundary; it did not
|
||||
reopen the active-construction contract.
|
||||
|
||||
This position completes the Stage 5 construction and probe boundary. It is not
|
||||
itself a release decision: the active-publication and truthful-attempt work in
|
||||
Stage 6 remains required. Complete retirement of the compatibility facade is
|
||||
not a prerequisite for issue 1140.
|
||||
This position completed the Stage 5 construction and probe boundary. At that
|
||||
intermediate point it was not itself a release decision: Stage 6 still had to
|
||||
complete the active-publication lifecycle and return an exact outcome for each
|
||||
attempt. Complete retirement of the compatibility facade was not a prerequisite
|
||||
for issue 1140.
|
||||
|
||||
## Stage 6: harden the active lifecycle and exact attempt outcome
|
||||
|
||||
@@ -342,8 +350,8 @@ publication.
|
||||
|
||||
The first implementation regressions cover:
|
||||
|
||||
- replacement waiting for an admitted exact-context task while ignoring an
|
||||
unrelated bounded activity;
|
||||
- replacement waiting for a task admitted against the exact publication while
|
||||
ignoring an unrelated bounded activity;
|
||||
- context acquisition waiting for a queued replacement rather than returning a
|
||||
stale or intermediate publication;
|
||||
- rejecting central-remote administration releasing its reservation before
|
||||
@@ -711,6 +719,7 @@ retirement remains a separately reviewed compatibility change.
|
||||
|
||||
## References
|
||||
|
||||
- [Project glossary](../glossary.md#developer-and-design-terms)
|
||||
- [Part 1: core contract](2026_08_replicator_capabilities_01_core_contract.md)
|
||||
- [Part 2: P2P service and session lifecycle](2026_08_replicator_capabilities_02_p2p_service_lifecycle.md)
|
||||
- [P2P Room and Transport Lifecycle](2026_07_p2p_transport_lifecycle.md)
|
||||
|
||||
@@ -7,7 +7,7 @@ Accepted for a limited implementation.
|
||||
## Problem and scope
|
||||
|
||||
This document uses the independent revision properties defined under
|
||||
[Revision](../terms.md#revision) and the general state model in
|
||||
[Revision](../glossary.md#revision) and the general state model in
|
||||
[Conflict resolution and revision provenance](../specs_conflict_resolution.md).
|
||||
|
||||
Document History can reconstruct an available historical revision from its
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
---
|
||||
date: 2026-09-03
|
||||
commonlib-version: "0.1.21"
|
||||
self-hosted-livesync-version: "1.0.24"
|
||||
commonlib-source-commit: e770f617ff0fc88f4823226b0ab3aefdff50cc1e
|
||||
status: accepted
|
||||
---
|
||||
|
||||
# Replicator architecture
|
||||
|
||||
This is the implemented architecture for Self-hosted LiveSync 1.0.24 with `@vrtmrz/livesync-commonlib` 0.1.21. It is an implementation overview for developers maintaining the composition or adding a built-in provider. The corresponding Commonlib source was inspected at commit `e770f617ff0fc88f4823226b0ab3aefdff50cc1e`.
|
||||
|
||||
## Status, scope, and source-of-truth boundary
|
||||
|
||||
The plug-in repository is the source of truth for host composition, host scheduling, Obsidian/CLI/WebApp/WebPeer integration, provider declarations, and host-owned resource adapters. Commonlib is the source of truth for the provider contract, the active-publication state machine, typed replication runners, P2P service ownership, and Journal transport primitives. This repository consumes Commonlib as the published `0.1.21` package; it does not maintain a source mirror or a generated fallback.
|
||||
|
||||
The implementation has three built-in providers:
|
||||
|
||||
- CouchDB, composed by this repository;
|
||||
- Object Storage, composed by this repository; and
|
||||
- P2P, composed by Commonlib's `useP2PReplicatorFeature` in each application runtime which supports it.
|
||||
|
||||
The catalogue is closed at host composition. `src/common/replicatorProviders.ts` exhaustively composes the central providers, while the Commonlib P2P feature composes its P2P provider. This is not a runtime third-party registry: a provider cannot be added by registering a name, loading a plug-in, or supplying a setting at runtime. Adding a provider means changing the relevant Commonlib and host composition, then shipping and testing that composition.
|
||||
|
||||
The three capability ADRs record the decisions which led to this shape. They are useful decision history, but this document describes the current implementation and its ownership boundaries rather than repeating the ADR sequence.
|
||||
|
||||
## Terminology
|
||||
|
||||
The [Project glossary](../glossary.md#developer-and-design-terms) is canonical
|
||||
for project-specific vocabulary in this document. In particular, see
|
||||
[Replicator](../glossary.md#replicator),
|
||||
[Replicator provider definition](../glossary.md#replicator-provider-definition),
|
||||
[Active publication](../glossary.md#active-publication),
|
||||
[Admission and reservation](../glossary.md#admission-and-reservation),
|
||||
[Configuration identity](../glossary.md#configuration-identity),
|
||||
[Capability](../glossary.md#capability),
|
||||
[Central remote](../glossary.md#central-remote),
|
||||
[Publication retirement](../glossary.md#publication-retirement), and
|
||||
[Fence, generation, and epoch](../glossary.md#fence-generation-and-epoch).
|
||||
The glossary also fixes the ownership meanings of
|
||||
[Adjunct P2P transport](../glossary.md#adjunct-p2p-transport),
|
||||
[Remote resource and probe](../glossary.md#remote-resource-and-probe),
|
||||
[Non-owning adapter](../glossary.md#non-owning-adapter),
|
||||
[P2P service, room session, and demand](../glossary.md#p2p-service-room-session-and-demand),
|
||||
[Interaction authority](../glossary.md#interaction-authority),
|
||||
[Journal remote epoch](../glossary.md#journal-remote-epoch),
|
||||
[Replication outcome](../glossary.md#replication-outcome), and
|
||||
[Suspension](../glossary.md#suspension).
|
||||
The user-facing glossary also distinguishes
|
||||
[OneShot Sync from Continuous replication](../glossary.md#user-facing-and-operational-terms).
|
||||
Names shown in code font are source identifiers, not additional prose terms.
|
||||
|
||||
## Ownership and topology
|
||||
|
||||
The portable topology below names ownership rather than merely call order. An arrow means that the object or layer composes, invokes, or owns the next item.
|
||||
|
||||
```text
|
||||
Application composition
|
||||
Obsidian main / CLI / WebApp --> LiveSyncBaseCore --+
|
||||
WebPeerRuntime ------------------------------------+--> Service Hub
|
||||
|
|
||||
+----------------------------------------+---------------------+
|
||||
| |
|
||||
v v
|
||||
ReplicatorService (Commonlib) ReplicationService (Commonlib)
|
||||
| |
|
||||
+--> closed provider catalogue +--> typed replication runners
|
||||
| CouchDB / Object Storage / P2P | readiness + outcomes
|
||||
| |
|
||||
+--> active publication <------ exact-publication admission ---+
|
||||
provider + instance + identity
|
||||
|
||||
useP2PReplicatorFeature (Commonlib)
|
||||
|
|
||||
+--> registers the P2P provider, whose factory creates non-owning active adapters
|
||||
|
|
||||
+--> stable P2P service views and lifecycle
|
||||
|
|
||||
+--> P2PRoomSessionOwner
|
||||
|
|
||||
+--> P2PAutomationCoordinator
|
||||
+--> current P2PRoomSession
|
||||
|
|
||||
+--> P2PHost / TrysteroReplicator
|
||||
|
|
||||
+--> Trystero room, relays, and physical peers
|
||||
```
|
||||
|
||||
`LiveSyncBaseCore` receives a Service Hub, registers the central provider definitions, composes `serviceFeature` functions, and retains only focused views. `WebPeerRuntime` composes directly over its browser Service Hub because it is a P2P-only host. The P2P feature is composed by each supporting application runtime, so the CLI and web applications can use the same transport ownership without making the active adapter a second owner.
|
||||
|
||||
| Owner | Responsibility | Explicitly does not own |
|
||||
| --- | --- | --- |
|
||||
| Host composition | Selects the closed provider catalogue, supplies host adapters, and registers features before lifecycle work begins. | Active-instance retirement or operation admission. |
|
||||
| Commonlib `ReplicatorService` | Provider registration, active publication, exact-publication reservations, serial lifecycle transitions, transfer stop during suspension or retirement, and physical close. | Replication readiness, trigger policy, or P2P room ownership. |
|
||||
| Commonlib `ReplicationService` and its typed coordinator | User and unattended OneShot dispatch, Continuous startup, readiness, interaction authority, finite-activity accounting, outcomes, and failure hand-off. | Active publication replacement or scheduling policy. |
|
||||
| Host replication scheduling `serviceFeature` | Decides when resume, Periodic, and Continuous requests may run, and fences stale scheduled work. | Provider construction, transfer mechanics, or active Replicator close. |
|
||||
| Provider definition and runner | Declares what one remote kind supports and adapts its transfer results to typed outcomes. | Selecting when a request should run. |
|
||||
| Stable P2P service and room-session owner | P2P demand, binding reconciliation, session retirement, finite room operations, automation state, and focused views. | The active P2P adapter's publication lifetime or Trystero's physical peers. |
|
||||
|
||||
## Request flow
|
||||
|
||||
1. Composition registers the central provider definitions before lifecycle-driven provider initialisation. P2P composition registers its own Commonlib provider and returns stable P2P views and lifecycle controls.
|
||||
2. `ReplicatorService` serialises setting realisation, active-provider initialisation, database lifecycle transitions, suspension, and unload. `ReplicationService` owns per-request readiness. Resume work is separately owned by the host scheduling feature and the P2P service lifecycle.
|
||||
3. `ReplicatorService` resolves the current `remoteType`, checks `isConfigured`, and computes the provider's opaque configuration identity. If the provider and identity are unchanged, the active publication is retained. If either changes, the replacement fence runs before a new publication is created.
|
||||
4. A typed operation such as `runUserInitiated`, `runUnattended`, or `startContinuous` acquires the current publication after earlier queued lifecycle transitions have settled. It checks interaction authority, capability support, and readiness in the order required by the request type, then takes an immutable settings snapshot.
|
||||
5. The operation admits a reservation against the exact publication and identity. The provider-specific runner owns the transfer; finite operations are counted as bounded remote activity, while continuous replication is not.
|
||||
6. Provider resources are created through the declared resource factories when a feature needs a connection, preferred-tweak, Security Seed, or synchronisation-information probe. Resource ownership is explicit, and owned resources are disposed in the caller's `finally` path.
|
||||
7. The runner returns a `ReplicationOutcome` rather than using `undefined` as a success signal. Documents delivered through `parseSynchroniseResult` are queued by the host result processor for local application; central compatibility recovery and Security Seed preflight remain host features around the typed operation.
|
||||
8. Automatic `database-event`, `editor-save`, `file-open`, `merge`, `resume`, `periodic`, and `daemon` requests select unattended authority explicitly. Unattended work cannot prompt, select a peer interactively, or silently fall back to a legacy capability.
|
||||
|
||||
The active publication may change while a request is being prepared. The reservation keeps the admitted old instance alive until the operation settles; a new request admitted after the queued transition observes the new publication. A callback which holds a reservation must not await a lifecycle transition which itself waits for that reservation.
|
||||
|
||||
## Provider contract and current capability matrix
|
||||
|
||||
The Commonlib contract is deliberately small. A provider definition supplies the following shape (with the exact generic types omitted here for readability):
|
||||
|
||||
```typescript
|
||||
{
|
||||
kind,
|
||||
diagnosticName,
|
||||
readiness,
|
||||
isConfigured(setting),
|
||||
configurationIdentity(setting),
|
||||
create(setting),
|
||||
remoteResources,
|
||||
centralRemoteAdministration?,
|
||||
userInitiatedOneShot,
|
||||
unattendedOneShot,
|
||||
continuous,
|
||||
stopActiveTransfer
|
||||
}
|
||||
```
|
||||
|
||||
`defineReplicatorProviderDefinitions` makes the definition map exhaustive for the selected `RemoteType` tuple and rejects duplicate, missing, extra, or mismatched runtime definitions. Capability declarations are explicit. `supported` adapts a provider runner to `ReplicationOutcome`; `not-implemented` and `not-applicable` produce typed blocked outcomes. The contract distinguishes user authority from `NO_INTERACTION`, so a provider cannot accidentally prompt from an unattended trigger.
|
||||
|
||||
The factory receives the fully merged effective settings. It returns a `ReplicatorInstance` with only four required lifecycle methods:
|
||||
|
||||
| Method | Contract |
|
||||
| --- | --- |
|
||||
| `initializeDatabaseForReplication()` | Prepare local state before publication. `false` rejects and disposes the candidate. |
|
||||
| `openReplication(setting, keepAlive, showResult, ignoreCleanLock)` | Retained compatibility entry point for finite or Continuous work. A typed provider runner must convert its `void` or Boolean settlement to an explicit outcome; `void` is not finite success. |
|
||||
| `terminateSync()` | Request cancellation of active transfer work and settle synchronously or asynchronously. It does not transfer ownership or replace physical close. |
|
||||
| `closeReplication()` | Release resources owned by this instance. It runs only after admitted work drains; a non-owning adapter, such as P2P, must leave service-owned resources alone. |
|
||||
|
||||
Provider-specific methods remain on provider-specific interfaces or host-owned adapters. They are not added to the generic contract merely because an old compatibility class exposed them.
|
||||
|
||||
### Current capability matrix
|
||||
|
||||
| Capability | CouchDB | Object Storage | P2P |
|
||||
| --- | --- | --- | --- |
|
||||
| Readiness | Central remote preparation required | Central remote preparation required | Central preparation not applicable; peer readiness is provider-owned |
|
||||
| Active Replicator factory | `LiveSyncCouchDBReplicator` | `LiveSyncJournalReplicator` | `P2PActiveReplicatorAdapter` over the stable P2P service |
|
||||
| User-initiated OneShot | Supported | Supported | Supported, with explicit peer selection |
|
||||
| Unattended OneShot | Supported | Supported | Supported for configured targets; no peer-selection prompt |
|
||||
| Continuous replication | Supported | Not applicable | Not applicable |
|
||||
| Stop active transfer | Supported | Supported | Supported; cancels finite operations while retaining the room when appropriate |
|
||||
| Connection resource | Supported | Supported | Not applicable |
|
||||
| Preferred-tweak resource | Supported | Supported | Not applicable |
|
||||
| Security Seed resource | Supported | Supported | Not applicable |
|
||||
| Synchronisation-information resource | Supported | Not applicable | Not applicable |
|
||||
| Central remote administration | CouchDB administration supported | Object Storage administration supported | Not applicable |
|
||||
|
||||
The matrix is the current host composition, not a promise that every provider must support every row. A new provider must declare every resource kind and every operation capability, using `not-applicable` where the concept does not exist. Central remote administration is a cohesive capability: it covers the applicable verification milestone and mark-resolved, lock, and unlock mutations rather than exposing individual legacy helpers as generic operations.
|
||||
|
||||
## Active Replicator lifecycle and exact replacement fence
|
||||
|
||||
Commonlib's `ReplicatorService` serialises lifecycle transitions on one queue. It owns the active publication, reservations against that publication, transfer stop, and final close. The effective configuration identity is deliberately opaque; comparing it is valid, but inspecting or persisting it is not.
|
||||
|
||||
```text
|
||||
absent
|
||||
|
|
||||
| configured lifecycle initialisation
|
||||
v
|
||||
candidate (private and not admitted)
|
||||
| \
|
||||
| initialised and current \ failed or stale --> closed; no active publication
|
||||
v
|
||||
active publication
|
||||
| \ same provider and identity --> retained
|
||||
| \ suspension ----------------> transfer stopped; publication retained
|
||||
|
|
||||
| provider, identity, database, or terminal lifecycle change
|
||||
v
|
||||
quiescing (removed from current; new admission fenced)
|
||||
|
|
||||
| stop --> drain exact reservations --> close --> complete retirement
|
||||
v
|
||||
absent --> optional replacement candidate
|
||||
```
|
||||
|
||||
For a provider or effective-configuration change, the exact fence is:
|
||||
|
||||
1. Enqueue the transition on the serial lifecycle queue.
|
||||
2. Read the current setting, resolve the closed provider definition, check `isConfigured`, and compute the effective identity.
|
||||
3. If the current publication has a different provider or identity, call `beginRetirement`. This stops new reservations and removes the publication from the current slot.
|
||||
4. Request the provider's `stopActiveTransfer` capability. The legacy `terminateSync` path is retained only for an untyped compatibility publication.
|
||||
5. Await settlement of reservations admitted from the retiring publication. New operations cannot enter it.
|
||||
6. Call the old instance's `closeReplication`.
|
||||
7. Mark the retirement complete. No publication is installed between removal of the old publication and this completion.
|
||||
8. Create a candidate through the provider definition, reset provider statistics, and yield the required microtask boundary.
|
||||
9. Initialise the candidate for the current database and run `onBeforeReplicatorPublication` handlers.
|
||||
10. Re-read the current setting, provider, and opaque identity. If any is stale, dispose the candidate and publish nothing; the queued lifecycle work will resolve the newer state.
|
||||
11. Publish the provider, candidate instance, and identity atomically as the new active publication.
|
||||
|
||||
The same provider and identity retain the current publication. Database initialisation is a lifecycle boundary even when the setting identity is unchanged: the old publication is retired before the physical local database is replaced, then a candidate is created for the new database. A failed or stale candidate leaves the service without an active publication; it is not silently substituted with a previous instance.
|
||||
|
||||
If transfer stop fails, retirement still proceeds to draining and physical close. If physical close rejects, retirement remains fenced and no replacement can be published; a later serial transition may retry the same retirement. The service never restores admission to a publication once retirement has begun.
|
||||
|
||||
## Generation and epoch fences
|
||||
|
||||
These values protect different state machines. They must not be collapsed into one general-purpose generation.
|
||||
|
||||
| Fence | Owner and representation | Changes when | Protects | Does not protect |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Active publication identity | Commonlib `ActiveReplicatorPublication` object, containing provider, instance, and opaque configuration identity; not a numeric counter | Provider/configuration replacement, or a database lifecycle replacement | Admission and completion against the exact active instance | Delayed scheduling, P2P automation baselines, or Journal remote-wipe decisions |
|
||||
| Host scheduling lifecycle generation | `ReplicationSchedulingContext.lifecycleGeneration` | Scheduling resumes after the lifecycle was disabled | Resume operations and timer callbacks from a previous host scheduling lifecycle | Provider replacement, P2P room callbacks, or Journal transfers |
|
||||
| P2P service lifecycle generation | Private `P2PServiceState.lifecycleGeneration` | Explicit disconnect or host lifecycle closure | Delayed P2P AutoStart and service-level automatic demand | A room's operation set, automation baseline, or remote Journal epoch |
|
||||
| P2P session object / epoch fence | The current `P2PRoomSession` object, its `acceptingOperations` flag, session abort signal, and the owner's lifecycle queue; there is no exported numeric P2P session epoch | Room binding replacement, retirement, or owner close | Room callbacks, finite operations, peer handlers, and stale candidate sessions | Cross-session automation deduplication and host scheduling |
|
||||
| P2P automation generation | `P2PAutomationCoordinator.generation` | `beginLifecycle` or effective identity reconciliation (namespace or database object) | Completed peer baseline publication and stale automation completions | Room ownership, explicit disconnect veto, and physical peer connection ownership |
|
||||
| Journal stop generation | `LiveSyncJournalReplicator.journalTransferStopGeneration` | `terminateSync` requests a stop | Admitted Journal transfers after setup and before `client.sync`; repeated stops share settlement | Provider publication identity and remote checkpoint/cache identity |
|
||||
| Journal remote epoch | `CheckPointInfo.journalEpoch`, derived as `protocolVersion:pbkdf2salt` | Successfully read sync parameters yield a different value; a subsequent history probe decides whether checkpoint caches must be reset | Journal checkpoint and deduplication-cache reconciliation across remote histories | Local cancellation, provider retirement, or transfer admission |
|
||||
|
||||
In particular, a numeric value in one row cannot be used as evidence that an operation in another row is current. Failure to read Journal sync parameters does not produce a new remote epoch, and a P2P transport replacement does not by itself clear the automation coordinator's completed-peer baseline.
|
||||
|
||||
## Suspension, terminal retirement, and database replacement
|
||||
|
||||
| Event | `ReplicatorService` publication | P2P service and adapter | Result |
|
||||
| --- | --- | --- | --- |
|
||||
| Application suspension | Requests `stopActiveTransfer` and retains the active publication | `closeForLifecycle` closes the current room/session and invalidates delayed automation; the active adapter is non-owning and does not close the service through `closeReplication` | Suspension is reversible. Resumption schedules the appropriate P2P AutoStart and host replication work. |
|
||||
| Provider setting or effective identity change | Runs the complete replacement fence | Reconciles or replaces the P2P room when its effective binding changes | The old publication/session cannot receive new work. |
|
||||
| Database replacement or rebuild | Retires and closes the active publication before physical database teardown; database-ready events permit reinitialisation | Closes the P2P room before database destruction and creates a binding for the new database object | No provider or room may retain the old database. |
|
||||
| Unload or terminal lifecycle close | Stops, drains, closes, and completes retirement; no active publication remains | `closeForLifecycle` clears owner demand, closes the current room, and invalidates automation | Terminal retirement is not resumed. |
|
||||
|
||||
Suspension and retirement therefore have different guarantees. `ReplicatorService` suspension stops transfer but intentionally retains the provider instance and publication. Terminal retirement removes admission, drains it, closes it, and does not publish a replacement unless a later lifecycle event explicitly initialises one. P2P transport is additionally closed on suspension because its service lifecycle owns a room session, but the active P2P adapter is only a compatibility handle and does not own that session.
|
||||
|
||||
## Owned resources and probes
|
||||
|
||||
| Resource or probe | Owner | Lifetime and disposal rule |
|
||||
| --- | --- | --- |
|
||||
| Active Replicator publication | Commonlib `ReplicatorService` | Publication retirement fences admission, drains reservations, calls `closeReplication`, and completes the retirement. |
|
||||
| Central connection probe | Host resource factory in `src/common/replicatorResources/connection.ts` | A caller-owned CouchDB or Object Storage snapshot backed by a concrete Replicator/connection; dispose it in `finally`. It does not replace the active publication. |
|
||||
| Preferred-tweak probe | Host `preferredTweak` resource factory | Read through the declared resource, then dispose the owned resource. |
|
||||
| Security Seed probe | Host `securitySeed` resource factory and the replication preflight | Use `createRemoteResource` and `withOwnedRemoteResource`; reject an empty seed and always dispose the resource. It does not assume that an active Replicator exists. |
|
||||
| Synchronisation-information probe | Host `synchronisationInformation` resource factory | Check or read through the resource and dispose it; an unavailable remote is not treated as a confirmed absence. |
|
||||
| Central administration operation | Provider administration runner | Uses its declared verification and mutation ownership. A fresh connection may be owned by the operation; an active Journal client borrowed from the active provider is not disposed by the borrower. |
|
||||
| Journal client and transfer set | `LiveSyncJournalReplicator` | The Journal Replicator owns the client and active transfer promises. `terminateSync` requests stop and awaits the shared settlement; `closeReplication` disposes the client without lazily creating one. |
|
||||
| P2P room/session, finite operation set, and relay actions | `P2PRoomSessionOwner` and current `P2PRoomSession` | The owner serialises binding and demand changes. Session retirement rejects admission, aborts and awaits operations, disables broadcast, and disposes the session Replicator. |
|
||||
| Physical Trystero peer connections | Trystero runtime | Commonlib must not close raw `room.getPeers()` connections merely because a logical room session retires; shared Trystero ownership may outlive an idle room callback. |
|
||||
| Physical local database | Commonlib DatabaseService | Database lifecycle owns teardown and readiness. Replicator and P2P owners close before the database is destroyed. |
|
||||
|
||||
Probe callers must use the resource capability rather than reaching through `LiveSyncBaseCore.replicator`. This keeps a short-lived observation from acquiring ownership of the active transfer or publication.
|
||||
|
||||
## P2P special ownership and the non-owning adapter
|
||||
|
||||
P2P is composed as a `serviceFeature` and has more state than a central provider. It can remain enabled as an adjunct while CouchDB or Object Storage is the selected main remote; `ReplicatorService` publishes the P2P active adapter only when `remoteType` is P2P. The active-publication owner and the room-session owner are therefore deliberately independent.
|
||||
|
||||
The stable service owns persistent demand (`explicit`, `automatic`, or `rebuild-continuation`), finite-operation demand, the lifecycle queue, the effective binding, and the current room session. The room owner compares the local database object separately and includes the effective device name in its binding signature, so the binding is not interchangeable with the P2P provider's active-publication configuration identity. The automation coordinator owns automation-baseline deduplication. The current `P2PRoomSession` owns one room, peer handlers, advertisements, RPC, session cancellation, and finite operations. Trystero owns shared relay clients and physical peer connections.
|
||||
|
||||
`P2PActiveReplicatorAdapter` implements the minimal `ReplicatorInstance` view required by the provider contract. Its `initializeDatabaseForReplication`, `openReplication`, and `terminateSync` methods delegate to the P2P service. Its `closeReplication` is intentionally a no-op: closing the active adapter must not close the room, relay actions, finite-operation registry, or stable P2P service. The service lifecycle (`closeForLifecycle`, owner close, or binding reconciliation) is the only owner which retires the room.
|
||||
|
||||
The P2P connection probe follows the same boundary. An active compatible room may be observed; an incompatible active binding blocks the probe. An idle probe can run a caller-owned trial through the owner queue and must await clean-up. It must not publish itself as the active room or close resources owned by another session.
|
||||
|
||||
Automatic configured-target replication acquires finite room demand, waits for peer advertisements within a bounded window, evaluates admission without prompting, shares the baseline through `P2PAutomationCoordinator`, and returns an explicit completed, partial, blocked, cancelled, or failed outcome. Explicit disconnect veto remains distinct from host lifecycle closure. AutoStart cannot clear an explicit disconnect veto; rebuild continuation is a separately authorised path.
|
||||
|
||||
## Adding a built-in provider
|
||||
|
||||
Provider work crosses the Commonlib package boundary and this repository's host composition. The following sequence is the smallest complete path; omit a step only when the provider genuinely has no corresponding concept.
|
||||
|
||||
### First decide whether this is a provider
|
||||
|
||||
A new provider is appropriate when a remote kind needs a distinct active Replicator lifecycle, effective configuration identity, readiness policy, or replication roles. A new S3-compatible service or another backend which retains the Object Storage Journal protocol is usually an `IJournalStorage` adapter instead; see [Journal Replicator 2nd Edition](../design_docs_of_journalsync_2nd.md). A new read-only observation over an existing provider is usually a remote resource or a focused view. Neither case needs another active provider.
|
||||
|
||||
1. **Define the canonical remote kind in Commonlib.** Add the `RemoteType` value and its setting type in `src/common/models/setting.const.ts` and `src/common/models/setting.type.ts`, update exports such as `src/common/types.ts`, and add defaults or persistence fields only where the provider needs them. Add focused setting and migration tests.
|
||||
2. **Implement the Replicator in Commonlib.** Place the provider-specific Replicator and transport code under `src/replication/<provider>/`. Implement the minimal `ReplicatorInstance` contract, cancellation, and close semantics. Keep provider-specific operations on focused facets. Add unit tests for success, cancellation, failure, stop, and replacement-sensitive clean-up.
|
||||
3. **Define effective configuration identity.** Include every setting which changes the live binding, and exclude profile labels or policy-only settings. Normalise two spellings only when the runtime genuinely treats them as equivalent. Put shared identity logic in Commonlib when the provider is shared there; put the host projection in `src/common/replicatorConfigurationIdentity.ts` when this repository owns it. Test that equivalent effective settings retain an instance and binding changes replace it. Never expose identity values in logs, UI, or persistence.
|
||||
4. **Add configuration and setup seams in Commonlib.** If the provider has a connection string, profile, migration, or document representation, update the applicable files, including `src/common/ConnectionString.ts`, `src/remoteConfigurations.ts`, `src/common/configForDoc.ts`, `src/API/processSetting.ts`, and their focused tests. These files are conditional: do not add a setting representation which the provider does not need.
|
||||
5. **Declare the provider contract surface at its composition owner.** Add a central provider to the tuple and definition map in this repository's `src/common/replicatorProviders.ts`; add a P2P-like provider to the closed tuple owned by its Commonlib `serviceFeature`. In the definition, declare readiness, all four remote-resource capability entries, user and unattended OneShot runners, Continuous where applicable, `stopActiveTransfer`, and central administration where applicable. Extend `RemoteResource` kinds only for a genuinely cross-provider resource; do not encode provider-specific helpers as generic capabilities.
|
||||
6. **Implement stateful transport ownership, if required.** For a P2P-like provider, add a stable service owner, focused views, lifecycle ownership, binding identity, session retirement, and automation fences in Commonlib, then compose it through a `serviceFeature`. Keep any active adapter non-owning if the service owns a replaceable transport. Add lifecycle, stale-callback, probe, and database-replacement tests before host integration.
|
||||
7. **Compose the provider in each supporting application.** Central definitions are registered by `LiveSyncBaseCore`. A dedicated stateful feature must be composed from the applicable hosts: `src/main.ts`, `src/apps/cli/main.ts`, `src/apps/webapp/WebAppRuntime.ts`, and `src/apps/webpeer/src/WebPeerRuntime.ts`. Each selected catalogue must remain exhaustive and closed; add no runtime provider registry.
|
||||
8. **Add host-owned resources and administration.** Add or extend `src/common/replicatorResources/` for connection, preferred-tweak, Security Seed, and synchronisation-information probes. Add provider-specific central verification and mutations in `src/common/centralRemoteAdministration.ts` when applicable. Test ownership, snapshots, the distinction between unavailable and absent states, postconditions, and disposal.
|
||||
9. **Integrate setup and user-facing configuration.** Update the relevant setup dialogue files under `src/modules/features/SetupWizard/dialogs/`, including `dialogs/setupDialogTypes.ts`, SetupManager or setup features, remote configuration handling, and message resources under `src/common/messagesYAML` plus generated baked messages where required. Follow the terminology and settings mappings in the repository documentation, and add setup, serialisation, and migration tests.
|
||||
10. **Integrate host operations and triggers.** Adapt only the capability call sites which the provider supports. Check `src/serviceFeatures/replicationScheduling.ts`, `src/serviceFeatures/replication/`, CLI commands under `src/apps/cli/commands`, and application-specific lifecycle composition. Ensure unattended paths use `NO_INTERACTION`, periodic and resume fallback obey capability outcomes, and no caller reaches for `getNewReplicator` or the `LiveSyncBaseCore.replicator` compatibility getter.
|
||||
11. **Validate the package boundary.** In Commonlib, run its focused unit tests, build or pack the exact candidate artefact, and test the downstream LiveSync consumer against that artefact. In this repository, run provider map, configuration-identity, resource, central-administration, scheduling, and replication-feature unit tests. Add a real remote integration test, CLI E2E coverage, or real Obsidian E2E coverage for every boundary the provider claims to support.
|
||||
|
||||
A provider is complete only when its source ownership, replacement fence, capability matrix, setup path, and tests agree. Updating a setting type or adding a class without adding the closed composition definition does not make it a built-in provider.
|
||||
|
||||
## Compatibility seams and non-goals
|
||||
|
||||
- `ReplicatorService.getNewReplicator`, `getActiveReplicator`, and the `LiveSyncBaseCore.replicator` getter remain compatibility seams for existing callers. Beyond `ReplicatorInstance`, `LiveSyncBaseCore.replicator` exposes provider-specific members only as an optional compatibility view. None is a new provider extension point.
|
||||
- `ReplicationService.performReplication` remains a direct legacy path through the active instance. New call sites use `replicateUserInitiated`, `replicateUnattended`, `replicateUnattendedByEvent`, `startContinuous`, or `stopActiveTransfer`, as appropriate.
|
||||
- `LiveSyncAbstractReplicator` and other legacy classes may retain methods needed by existing modules. New features use typed provider capabilities, resource factories, and focused service views; they do not infer capabilities from a large legacy class.
|
||||
- The generic contract does not unify directional Journal operations, Streaming replication, Chunk retrieval, remote-size inspection, garbage collection, repair workflows, or provider-specific administration. Those remain explicit provider or host features.
|
||||
- The provider catalogue is not a public runtime registry, dynamic plug-in API, or settings-driven discovery mechanism. Unknown `RemoteType` values are composition/configuration failures, not third-party providers which the runtime should load.
|
||||
- Commonlib remains an external authoritative package. This repository must not recreate `src/lib`, `_types`, or another source mirror to bypass the package boundary.
|
||||
- P2P logical room retirement does not authorise closing shared raw `RTCPeerConnection` objects. Physical transport ownership remains with Trystero.
|
||||
- No numeric P2P session epoch is exported. Session object identity, admission flags, abort signals, and the owner queue provide the fence; the P2P automation generation and the host scheduling generation protect different concerns.
|
||||
- Suspension is not a database replacement or a successful replication result. It stops or closes the appropriate active work and relies on the next lifecycle event to resume, reconcile, or retire it.
|
||||
|
||||
## Source map
|
||||
|
||||
### This repository
|
||||
|
||||
| Concern | Source and tests |
|
||||
| --- | --- |
|
||||
| Host composition and compatibility boundary | [`LiveSyncBaseCore.ts`](../../src/LiveSyncBaseCore.ts), [`main.ts`](../../src/main.ts), [`src/apps/cli/main.ts`](../../src/apps/cli/main.ts), [`WebAppRuntime.ts`](../../src/apps/webapp/WebAppRuntime.ts), [`WebPeerRuntime.ts`](../../src/apps/webpeer/src/WebPeerRuntime.ts) |
|
||||
| Closed central provider map | [`replicatorProviders.ts`](../../src/common/replicatorProviders.ts), [`replicatorProviders.unit.spec.ts`](../../src/common/replicatorProviders.unit.spec.ts) |
|
||||
| Provider identities and resources | [`replicatorConfigurationIdentity.ts`](../../src/common/replicatorConfigurationIdentity.ts), [`replicatorResources/`](../../src/common/replicatorResources/index.ts), [`replicatorResources.unit.spec.ts`](../../src/common/replicatorResources.unit.spec.ts) |
|
||||
| Central administration and preflight | [`centralRemoteAdministration.ts`](../../src/common/centralRemoteAdministration.ts), [`centralRemoteAdministration.unit.spec.ts`](../../src/common/centralRemoteAdministration.unit.spec.ts), [`replication/preflight.ts`](../../src/serviceFeatures/replication/preflight.ts) |
|
||||
| Host scheduling and replication feature | [`replicationScheduling.ts`](../../src/serviceFeatures/replicationScheduling.ts), [`replicationScheduling.unit.spec.ts`](../../src/serviceFeatures/replicationScheduling.unit.spec.ts), [`replication/index.ts`](../../src/serviceFeatures/replication/index.ts) |
|
||||
| Service graph and bounded local activity | [`ObsidianServices.ts`](../../src/modules/services/ObsidianServices.ts), [`ObsidianServiceHub.ts`](../../src/modules/services/ObsidianServiceHub.ts) |
|
||||
| Architecture guidance | [`devs.md`](../../devs.md), [Service feature and legacy Module boundaries](service_feature_and_legacy_module_boundaries.md), [Project glossary](../glossary.md), [Documentation style and vocabulary conventions](../terms.md), [`docs/settings.md`](../settings.md), [`docs/troubleshooting.md`](../troubleshooting.md) |
|
||||
|
||||
### Commonlib 0.1.21
|
||||
|
||||
The exact package tree described here is [pinned at commit `e770f617ff0fc88f4823226b0ab3aefdff50cc1e`](https://github.com/vrtmrz/livesync-commonlib/tree/e770f617ff0fc88f4823226b0ab3aefdff50cc1e). The source and design-document links below target that commit.
|
||||
|
||||
| Concern | Commonlib source or design document at the pinned commit |
|
||||
| --- | --- |
|
||||
| Provider contract, outcomes, identities, and resource capabilities | [`src/replication/ReplicatorInstance.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/ReplicatorInstance.ts), [`src/replication/ReplicatorProvider.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/ReplicatorProvider.ts), [`src/replication/RemoteResource.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/RemoteResource.ts), [`src/replication/CentralRemoteAdministration.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/CentralRemoteAdministration.ts), [`src/replication/CentralCompatibility.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/CentralCompatibility.ts) |
|
||||
| Active publication and typed operations | [`src/services/base/ReplicatorService.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/services/base/ReplicatorService.ts), [`activeReplicatorState.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/services/base/ReplicatorService.activeReplicatorState.ts), [`typedReplication.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/services/base/ReplicationService.typedReplication.ts), [`readiness.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/services/base/ReplicationService.readiness.ts) |
|
||||
| P2P service, room ownership, and automation | [`P2PService.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/p2p/P2PService.ts), [`P2PRoomSessionOwner.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/trystero/P2PRoomSessionOwner.ts), [`P2PRoomSession.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/trystero/P2PRoomSession.ts), [`useP2PReplicatorFeature.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/trystero/useP2PReplicatorFeature.ts), [`P2PAutomationCoordinator.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/trystero/P2PAutomationCoordinator.ts) |
|
||||
| P2P lifecycle design | [`docs/p2p-transport-lifecycle.md`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/docs/p2p-transport-lifecycle.md) |
|
||||
| Database and service-feature lifecycle | [`docs/database-lifecycle.md`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/docs/database-lifecycle.md), [`docs/service-feature-composition.md`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/docs/service-feature-composition.md), [`docs/settings-lifecycle.md`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/docs/settings-lifecycle.md) |
|
||||
| Journal transfer and remote epoch | [`LiveSyncJournalReplicator.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/journal/LiveSyncJournalReplicator.ts), [`JournalSyncCore.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/journal/JournalSyncCore.ts), [`JournalSyncTypes.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/journal/JournalSyncTypes.ts) |
|
||||
| Journal storage adapter boundary | [`JournalStorageAdapter.ts`](https://github.com/vrtmrz/livesync-commonlib/blob/e770f617ff0fc88f4823226b0ab3aefdff50cc1e/src/replication/journal/objectstore/JournalStorageAdapter.ts) |
|
||||
|
||||
### Decision records
|
||||
|
||||
- [Core provider contract and capabilities ADR](../adr/2026_08_replicator_capabilities_01_core_contract.md)
|
||||
- [P2P service lifecycle ADR](../adr/2026_08_replicator_capabilities_02_p2p_service_lifecycle.md)
|
||||
- [Replicator migration plan ADR](../adr/2026_08_replicator_capabilities_03_migration_plan.md)
|
||||
- [P2P Room and Transport Lifecycle ADR](../adr/2026_07_p2p_transport_lifecycle.md)
|
||||
- [Bounded Remote Activity ADR](../adr/2026_07_bounded_remote_activity.md)
|
||||
@@ -0,0 +1,384 @@
|
||||
---
|
||||
date: 2026-09-03
|
||||
commonlib-version: "0.1.21"
|
||||
self-hosted-livesync-version: "1.0.24"
|
||||
status: accepted
|
||||
---
|
||||
|
||||
# Project glossary
|
||||
|
||||
This glossary records stable, project-specific meanings used by Self-hosted
|
||||
LiveSync. Ordinary English and established technology terms retain their usual
|
||||
meanings unless they are defined here. Exact code identifiers, API names, and
|
||||
user-interface labels retain their source spelling.
|
||||
|
||||
The sections describe the intended audience, not a visibility guarantee. A
|
||||
term in the developer and design section can appear in code, tests, logs, or
|
||||
diagnostics. That does not make it user-interface vocabulary or a public
|
||||
extension contract.
|
||||
|
||||
## User-facing and operational terms
|
||||
|
||||
These terms can appear in the user interface, user documentation, setup and
|
||||
recovery guidance, or diagnostics intended for users.
|
||||
|
||||
### A–R
|
||||
|
||||
- **Boot-up sequence (boot sequence):** The initialisation process of the
|
||||
plug-in when Obsidian starts. It begins with loading the plug-in, setting up
|
||||
core services, loading saved settings, and opening the local database. After
|
||||
the layout is ready, the plug-in checks for flag files, runs configuration
|
||||
diagnostics, connects to the remote database, and begins file watching. The
|
||||
sequence finishes when the plug-in is ready and operational.
|
||||
- **Broken files (size mismatch):** A state where a file's Metadata and the
|
||||
content stored in its Chunks do not match, causing file retrieval or
|
||||
synchronisation failures. Inspect these mismatches with **Inspect conflicts
|
||||
and file/database differences** in the Hatch pane, then handle one exact
|
||||
revision at a time.
|
||||
- **Chunk / Chunks:** Divided units of data stored in the database or Object
|
||||
Storage to support efficient synchronisation.
|
||||
- **Compaction:** A database maintenance procedure which discards old
|
||||
historical document revisions to reduce remote database size.
|
||||
- **Continuous replication:** A provider's long-running replication mode. It
|
||||
remains active to exchange changes until stopped and is distinct from a
|
||||
finite OneShot Sync operation.
|
||||
- **Custom HTTP Handler / Use Internal API (CORS bypass settings):** Settings
|
||||
which bypass CORS restrictions by routing requests through Obsidian's native
|
||||
request APIs. There are separate settings for each central remote type:
|
||||
- **S3-compatible Object Storage (`useCustomRequestHandler`):** Labelled
|
||||
**Use Custom HTTP Handler** in the standard settings tab and **Use internal
|
||||
API** in the Svelte Setup Wizard dialogue. It is represented as `useProxy`
|
||||
in Setup URI query parameters for compatibility.
|
||||
- **CouchDB (`useRequestAPI`):** Labelled **Use Request API to avoid
|
||||
inevitable CORS problem** in the standard settings tab and **Use Internal
|
||||
API** in the Svelte Setup Wizard dialogue. It is represented as
|
||||
`useRequestAPI` in Setup URI query parameters.
|
||||
- **Customisation Sync:** The feature which synchronises settings, snippets,
|
||||
themes, and plug-ins. Write 'Customisation' with an 's' in documentation;
|
||||
technical configuration and links can use `customization` where required.
|
||||
- **Database Adapter (IDB and IndexedDB):** The local database storage
|
||||
interface used by PouchDB. The `IDB` adapter is recommended because the older
|
||||
`IndexedDB` adapter is obsolete and can cause memory leaks in LiveSync mode.
|
||||
Switching adapters requires local data migration and an Obsidian restart,
|
||||
but not a full database rebuild.
|
||||
- **Database Suffix (`additionalSuffixOfDatabaseName`):** A suffix appended to
|
||||
the database name so that multiple Vaults with the same name can synchronise
|
||||
to the same remote server.
|
||||
- **E2EE Algorithm:** The cryptographic algorithm version used for end-to-end
|
||||
encryption. All synchronising devices must use a compatible version, such as
|
||||
`V2` or `V1`.
|
||||
- **Eden (Eden Chunks):** A sunset-compatibility optimisation in which newly
|
||||
created Chunks are held inside the document until they stabilise, before
|
||||
becoming independent Chunks.
|
||||
- **Fast Setup (Simple Fetch):** The preferred automated initial
|
||||
synchronisation flow for a secondary device. It uses Streaming replication
|
||||
for the initial download and delays local file reflection to avoid temporary
|
||||
synchronisation warnings.
|
||||
- **Fast Fetch:** The CouchDB-specific Streaming replication path used by Fast
|
||||
Setup. It reads the changes feed in bounded pages and persists a checkpoint
|
||||
so an interrupted transfer can resume. An ineligible transport uses the
|
||||
ordinary fetch path instead.
|
||||
- **Flag files (`redflag.md`, `redflag2.md`, and `redflag3.md`):** Special
|
||||
Markdown files or directories at the Vault root which stop the boot-up
|
||||
sequence or trigger recovery work. `redflag.md` suspends all processes,
|
||||
`redflag2.md` (`flag_rebuild.md`) triggers a full database rebuild, and
|
||||
`redflag3.md` (`flag_fetch.md`) discards and fetches the local database again.
|
||||
- **Garbage Collection (GC):** The maintenance process which identifies Chunk
|
||||
documents not reachable from a current file or conflict branch, records
|
||||
logical deletions for them, propagates those deletions, and requests remote
|
||||
compaction to reclaim storage.
|
||||
- **Hatch (Hatch pane):** The troubleshooting and maintenance section in the
|
||||
plug-in settings. It contains diagnostics, database reset controls, status
|
||||
reports, and advanced edge-case settings.
|
||||
- **Hidden File Sync:** The feature which synchronises files in hidden
|
||||
directories, such as `.obsidian`.
|
||||
- **JWT Authentication:** An experimental CouchDB authentication option which
|
||||
uses a JSON Web Token instead of standard credentials. It requires a private
|
||||
key or secret, algorithm, expiry duration, subject, and key ID.
|
||||
- **LiveSync:** This name has two established meanings: the shortened plug-in
|
||||
name for Self-hosted LiveSync, and the Sync Mode for continuous, real-time
|
||||
synchronisation. Prefer 'Continuous replication' in design documentation
|
||||
when the mode, rather than the product, is meant.
|
||||
- **livesync-serverpeer / WebPeer:** Specialised clients which assist WebRTC
|
||||
peer-to-peer communication.
|
||||
- **Metadata (file metadata):** A database document which stores file
|
||||
properties, including its name, path, size, modification time, and references
|
||||
to the Chunks containing its content. PouchDB or CouchDB revision metadata
|
||||
carries conflict state; the file Metadata document has no separate history
|
||||
field. Metadata and file content are stored separately.
|
||||
- **OneShot Sync (OneShot replication):** One finite bidirectional
|
||||
synchronisation operation, normally pull then push, which is requested
|
||||
directly or by an event. It is distinct from Continuous replication.
|
||||
- **Overwrite Server Data with This Device's Files:** A maintenance operation,
|
||||
formerly named `Rebuild everything`, which discards the remote database and
|
||||
rebuilds the local and remote databases from the current files on one
|
||||
authoritative device.
|
||||
- **Path Obfuscation:** A privacy option which encrypts file paths and folder
|
||||
names on the remote server.
|
||||
- **plug-in:** The spelling used in user-facing messages and general prose.
|
||||
Retain `plugin` in code, configuration, and established technical names.
|
||||
- **Remediation (`maxMTimeForReflectEvents`):** A recovery setting which limits
|
||||
reflection of changes from the database to the Vault by ignoring file events
|
||||
after a specified date and time.
|
||||
- **Reset Synchronisation on This Device:** A maintenance operation, formerly
|
||||
named `Fetch everything`, which discards the local database and rebuilds it
|
||||
from the remote database.
|
||||
|
||||
### Revision
|
||||
|
||||
A revision is a version of one PouchDB or CouchDB document. Concurrent changes
|
||||
can form a revision tree with more than one current branch.
|
||||
|
||||
Revision modifiers describe independent properties. More than one can apply to
|
||||
the same revision:
|
||||
|
||||
- **leaf:** Has no known child revision.
|
||||
- **winner:** Is the leaf selected by PouchDB or CouchDB as the current
|
||||
document.
|
||||
- **conflict:** Is another current leaf which was not selected as the winner.
|
||||
- **Vault-matching:** Represents the same file content, or the same absent-file
|
||||
state, as the current Vault. More than one revision can match.
|
||||
- **displayed:** Is recorded by valid device-local file provenance as the
|
||||
branch represented in the Vault. A pending local edit might no longer match
|
||||
its bytes, but still extends this recorded branch.
|
||||
- **logically deleted:** Represents absence of the file through a deletion
|
||||
marker. A logically deleted revision can also be a leaf, winner, conflict,
|
||||
or Vault-matching revision. An absent file retains no displayed provenance.
|
||||
|
||||
Avoid 'live revision' because it can mean either a current leaf or a
|
||||
non-deleted revision. See
|
||||
[Independent revision properties](specs_conflict_resolution.md#independent-revision-properties)
|
||||
for the relationship between revision-tree roles, Vault state, and
|
||||
device-local provenance.
|
||||
|
||||
### S–Z
|
||||
|
||||
- **Scram (Scram Switches):** Emergency controls which suspend file watching or
|
||||
database reflection to reduce the risk of corruption or unintended changes.
|
||||
- **Security Seed:** The remote PBKDF2 salt used to derive the encryption key
|
||||
for replication. It must be read from, or established on, the remote before
|
||||
encrypted synchronisation.
|
||||
- **Segmenter (Segmented-splitter):** A chunking method which divides files at
|
||||
semantic boundaries, such as paragraphs or sections, rather than arbitrary
|
||||
byte boundaries.
|
||||
- **Self-hosted LiveSync:** The name of this plug-in. 'Self-hosted' is one
|
||||
hyphenated word.
|
||||
- **Setting Doctor (Config Doctor):** A diagnostic utility which identifies
|
||||
configuration mismatches or suboptimal settings and presents recommended
|
||||
values and reasons.
|
||||
- **Setup URI:** An encrypted representation of plug-in settings and remote
|
||||
configuration which can be transferred to another device and opened with a
|
||||
passphrase.
|
||||
- **Signalling relay (P2P):** A Nostr-compatible WebSocket relay used for peer
|
||||
discovery and WebRTC connection negotiation. It does not store or transfer
|
||||
Vault content. The project author operates a public relay as a best-effort
|
||||
convenience, and users can supply another compatible relay.
|
||||
- **Streaming replication (stream-based replication):** A transfer method
|
||||
which downloads database documents as a continuous stream of events. Fast
|
||||
Setup uses it to retrieve remote Metadata efficiently.
|
||||
- **Sync Mode:** The trigger mechanism for synchronisation. Current modes are
|
||||
**LiveSync**, for continuous replication, **Periodic Sync**, for work at a
|
||||
configured interval, and **On Events**, for configured application events.
|
||||
- **Synchronising devices:** Devices which participate in the same
|
||||
synchronisation for a Vault. The term describes membership rather than
|
||||
current activity, so it includes offline and idle devices.
|
||||
- **TURN Server (WebRTC P2P):** A Traversal Using Relays around NAT server used
|
||||
as an optional fallback when NAT or firewall rules prevent a direct WebRTC
|
||||
connection. It relays encrypted WebRTC traffic and is distinct from the
|
||||
signalling relay.
|
||||
- **Update Thinning (Batch database update):** An optimisation which groups
|
||||
local file edits over a short delay before committing them to the local
|
||||
database, reducing database writes.
|
||||
- **WebRTC P2P (peer-to-peer):** A synchronisation method which allows devices
|
||||
to communicate directly without a central remote database.
|
||||
|
||||
## Developer and design terms
|
||||
|
||||
These definitions are stable vocabulary for architecture documents, ADRs,
|
||||
implementation, tests, and code review. They might never appear in the user
|
||||
interface. Inclusion here fixes their project meaning; it does not make the
|
||||
named surface a public API or extension point.
|
||||
|
||||
### Active publication
|
||||
|
||||
The atomic publication of one Replicator provider, its `ReplicatorInstance`,
|
||||
and its configuration identity, owned by Commonlib's `ReplicatorService`. Its
|
||||
object identity is the admission fence for operations. An active publication
|
||||
is also called the active Replicator publication, and its instance is the
|
||||
**active Replicator**. 'Active publication' is more precise than 'current
|
||||
Replicator' when admission or retirement matters.
|
||||
|
||||
### Adjunct P2P transport
|
||||
|
||||
P2P operating as an additional transport while CouchDB or Object Storage is
|
||||
the selected main remote. It retains its own service and room-session
|
||||
ownership; it is not the active Replicator for the main remote. Architecture
|
||||
documents can shorten this to 'adjunct P2P' where the distinction is already
|
||||
clear.
|
||||
|
||||
### Admission and reservation
|
||||
|
||||
**Admission** is permission for an operation to use one exact active
|
||||
publication or P2P room session. A **reservation** records admitted work and
|
||||
keeps its owner alive until that work settles. Retirement closes admission
|
||||
before it waits for existing reservations, so later work cannot enter the
|
||||
retiring generation.
|
||||
|
||||
### Bounded remote activity
|
||||
|
||||
A finite logical operation which can involve remote work, waiting, queueing, or
|
||||
local result handling. Its lifetime is broader than an individual network
|
||||
request. Continuous replication is not bounded remote activity. See the
|
||||
[Bounded Remote Activity ADR](adr/2026_07_bounded_remote_activity.md).
|
||||
|
||||
### Capability
|
||||
|
||||
A typed declaration that a Replicator provider supports an operation or remote
|
||||
resource, does not implement it, or considers it inapplicable. Capability
|
||||
support is explicit; callers do not infer it from a legacy method, a Boolean
|
||||
default, or a neutral return value.
|
||||
|
||||
### Central remote
|
||||
|
||||
A CouchDB or Object Storage remote which can require central preparation and
|
||||
administration before replication. P2P is not a central remote. The **main
|
||||
remote** is the `RemoteType` selected for the active Replicator; P2P can also
|
||||
operate as an additional transport when a central remote is selected.
|
||||
|
||||
### Configuration identity
|
||||
|
||||
An opaque projection of the effective settings which determine whether an
|
||||
existing provider instance or P2P binding can be retained. It can contain
|
||||
credentials. Code can compare an identity for equality, but must not inspect,
|
||||
log, persist, or display it.
|
||||
|
||||
### Fence, generation, and epoch
|
||||
|
||||
A **fence** prevents stale work or work admitted by one owner from affecting a
|
||||
replacement owner or state. A **generation** normally changes when one local
|
||||
lifecycle is invalidated. An **epoch** identifies one session or data history
|
||||
where the owning contract uses that term. These values belong to distinct state
|
||||
machines and are not interchangeable or evidence that another owner is
|
||||
current.
|
||||
|
||||
### Focused view
|
||||
|
||||
A narrow interface exposing only the operations required by a consumer. It
|
||||
delegates to a stable owner and does not independently own the underlying
|
||||
mutable state or resource.
|
||||
|
||||
### Interaction authority
|
||||
|
||||
The explicit upper bound on user interaction permitted during an operation.
|
||||
User-initiated work can receive selected permissions; unattended work carries
|
||||
`NO_INTERACTION` and cannot open a dialogue, request peer selection, or obtain
|
||||
authority through a fallback path.
|
||||
|
||||
### Journal remote epoch
|
||||
|
||||
The `protocolVersion:pbkdf2salt` value stored as
|
||||
`CheckPointInfo.journalEpoch`. It identifies Journal checkpoint and
|
||||
deduplication-cache history. It is data-history state, not a cancellation,
|
||||
Replicator retirement, or operation-admission fence.
|
||||
|
||||
### Non-owning adapter
|
||||
|
||||
An adapter which implements a contract by delegating to another component
|
||||
without owning the delegated resource. Closing it releases only resources
|
||||
which the adapter itself owns. In particular, closing the active P2P adapter
|
||||
does not close the stable P2P service or its room session.
|
||||
|
||||
### Owner and ownership
|
||||
|
||||
The **owner** is the single component responsible for creating, replacing,
|
||||
stopping, and disposing a resource or stateful lifecycle. A borrower, adapter,
|
||||
or focused view can use that resource only within its declared boundary and
|
||||
must not perform the owner's lifecycle operations.
|
||||
|
||||
### P2P service, room session, and demand
|
||||
|
||||
The **P2P service** is the stable Commonlib owner which supplies focused views
|
||||
and owns replaceable room sessions. A **P2P room session** is one active room
|
||||
membership and the resources whose validity depends on it. **Demand** is one
|
||||
persistent or finite reason for the owner to retain a room. Releasing one
|
||||
demand does not close a room retained by another. A room's effective binding
|
||||
includes the settings, local database object, and device identity which make
|
||||
that session valid. A **session epoch** is the internal identity and fence of
|
||||
one room-session object, not a persisted room name or a public numeric counter.
|
||||
An **automation baseline** records peers for which the initial transfer
|
||||
completed in the current logical automation lifecycle; it is owned
|
||||
independently of a replaceable room session. A **configured target** is a
|
||||
persisted peer name selected for unattended `P2P_SyncOnReplication`; the
|
||||
request can wait for its advertisement, but cannot prompt for peer selection.
|
||||
|
||||
### Publication retirement
|
||||
|
||||
The lifecycle transition which removes an active publication from current
|
||||
admission, asks its provider to stop transfer work, drains reservations for
|
||||
that exact publication, closes the old instance, and marks retirement
|
||||
complete. **Quiescing** is the state after admission has closed and before
|
||||
retirement completes. A replacement cannot be published across an incomplete
|
||||
retirement fence. A **candidate** is a newly constructed instance which remains
|
||||
private until initialisation and freshness checks permit atomic publication.
|
||||
|
||||
### Remote resource and probe
|
||||
|
||||
A **remote resource** is a provider-declared, caller-owned object created from
|
||||
one effective-settings snapshot for a bounded task. A **probe** is a bounded,
|
||||
flow-specific validation or observation for connection, compatibility, setup,
|
||||
or diagnostics. It can use an owned remote resource or an owner-arbitrated P2P
|
||||
trial. It does not publish or replace the active Replicator, and the caller
|
||||
disposes every resource which it owns.
|
||||
|
||||
### Replicator
|
||||
|
||||
The project abstraction which performs replication for one configured remote
|
||||
kind and implements the `ReplicatorInstance` lifecycle contract. Use
|
||||
'replication' for the process and 'Replicator' for this runtime abstraction. A
|
||||
Replicator can be an owning transport implementation or a non-owning adapter;
|
||||
the provider contract determines the boundary.
|
||||
|
||||
### Replicator provider definition
|
||||
|
||||
The exhaustive, host-composed declaration for one `RemoteType`: its
|
||||
configuration identity, Replicator factory, readiness requirement,
|
||||
capabilities, remote-resource factories, operation runners, and optional
|
||||
central administration. The readiness requirement declares which layer must
|
||||
establish operation preconditions. The provider catalogue is **closed
|
||||
composition**, not a runtime registry: adding a provider requires changing,
|
||||
shipping, and testing the owning composition. A **built-in provider** is one
|
||||
included in that shipped catalogue. Architecture prose can shorten 'Replicator
|
||||
provider definition' to 'provider'; it does not mean only the transport
|
||||
instance.
|
||||
|
||||
### Replication outcome
|
||||
|
||||
The typed settlement of an attempted replication operation, represented by
|
||||
`ReplicationOutcome`. Completed, partial, blocked, cancelled, and failed states
|
||||
remain explicit; `undefined`, an empty value, or a compatibility default is not
|
||||
treated as successful work.
|
||||
|
||||
### Service composition terms
|
||||
|
||||
- A **Service Hub** is the long-lived registry of service contracts for one
|
||||
application composition.
|
||||
- A **Service** owns a stable shared capability and its lifecycle.
|
||||
- A **ServiceModule** is a host-created, long-lived stateful or resource-owning
|
||||
capability shared through the typed `ServiceModules` record.
|
||||
- A **serviceFeature** is a typed composition function which accepts declared
|
||||
Services and ServiceModules, registers host integration, and can return a
|
||||
focused view. It is not a runtime registry entry.
|
||||
- A **legacy Module** is an existing application structure retained for
|
||||
compatibility. New behaviour does not acquire the complete core merely to
|
||||
imitate that locator pattern.
|
||||
|
||||
See [Service feature and legacy Module boundaries](design_docs/service_feature_and_legacy_module_boundaries.md)
|
||||
for the selection and composition rules.
|
||||
|
||||
### Suspension
|
||||
|
||||
A reversible lifecycle action which stops active transfer work without
|
||||
retiring the active Replicator publication. The P2P service also closes its
|
||||
current room session during application suspension because that session has a
|
||||
separate owner and lifecycle. Resumption can retain the Replicator instance and
|
||||
open a new P2P room as required.
|
||||
@@ -20,7 +20,7 @@ Resolving a conflict writes the selected or merged result on one observed branch
|
||||
|
||||
### Independent revision properties
|
||||
|
||||
The modifiers defined under [Revision](terms.md#revision) describe independent properties, rather than exclusive revision types. The winner is a database-tree role, Vault-matching describes current file-state equality, and displayed identifies the device-local branch recorded for the Vault. The same revision commonly has all three properties, but synchronisation, conflicts, local edits, and missing provenance can separate them.
|
||||
The modifiers defined under [Revision](glossary.md#revision) describe independent properties, rather than exclusive revision types. The winner is a database-tree role, Vault-matching describes current file-state equality, and displayed identifies the device-local branch recorded for the Vault. The same revision commonly has all three properties, but synchronisation, conflicts, local edits, and missing provenance can separate them.
|
||||
|
||||
| Situation | Winner | Vault-matching | Displayed |
|
||||
| ---------------------------------------------------- | ------------------ | --------------------------------------------------- | ---------------------------------------------------- |
|
||||
|
||||
+9
-94
@@ -1,3 +1,10 @@
|
||||
---
|
||||
date: 2026-09-03
|
||||
commonlib-version: "0.1.21"
|
||||
self-hosted-livesync-version: "1.0.24"
|
||||
status: accepted
|
||||
---
|
||||
|
||||
# Notes on Terminology, Spelling, Vocabulary Conventions
|
||||
|
||||
## Spelling and Vocabulary conventions
|
||||
@@ -24,97 +31,5 @@ All guidelines and conventions listed below are disclosed and maintained solely
|
||||
|
||||
### Terminology
|
||||
|
||||
- Boot-up sequence (boot-sequence)
|
||||
- The initialisation process of the plug-in when Obsidian starts. It starts with the loading of the plug-in, setting up core services, loading saved settings, and opening the local database. Once the layout is ready, the plug-in checks for the presence of flag files, runs configuration diagnostics, connects to the remote database, and begins file watching. The sequence finishes once the plug-in is fully ready and operational.
|
||||
- Broken files (Size mismatch)
|
||||
- A state where a file's metadata and the actual content stored in its chunks do not match, causing file retrieval or synchronisation failures. These mismatches can be inspected with `Inspect conflicts and file/database differences` on the Hatch pane, then handled one exact revision at a time.
|
||||
- Chunk / Chunks
|
||||
- Divided units of data stored in the database or object storage to facilitate efficient synchronisation.
|
||||
- Compaction
|
||||
- A database maintenance procedure that discards old historical document revisions to shrink the remote database size.
|
||||
- Custom HTTP Handler / Use Internal API (CORS Bypass Settings)
|
||||
- Settings used to bypass CORS restrictions by routing requests through Obsidian's native request APIs. There are two distinct settings under the hood depending on the remote server type:
|
||||
- **For S3-compatible Object Storage (useCustomRequestHandler)**: Labeled as **"Use Custom HTTP Handler"** in the standard settings tab, **"Use internal API"** in the Svelte-based Setup Wizard dialogue, and represented as `useProxy` in the Setup URI's query parameters due to an unfortunate misunderstanding during development.
|
||||
- **For CouchDB (useRequestAPI)**: Labeled as **"Use Request API to avoid `inevitable` CORS problem"** in the standard settings tab, **"Use Internal API"** in the Svelte-based Setup Wizard dialogue, and represented as `useRequestAPI` in the Setup URI's query parameters.
|
||||
- Customisation Sync
|
||||
- The feature that synchronises settings, snippets, themes, and plug-ins. Write with an "s" in documentation (`Customisation`), though technical configurations and links may use `customization`.
|
||||
- Database Adapter (IDB vs. IndexedDB)
|
||||
- The local database storage interface used by PouchDB. The `IDB` adapter is recommended since the older `IndexedDB` adapter is obsolete and known to cause memory leaks in `LiveSync` mode. Users can switch between these adapters without a full database rebuild, although a local data migration and an Obsidian restart are required.
|
||||
- Database Suffix (additionalSuffixOfDatabaseName)
|
||||
- A unique suffix appended to the database name to allow synchronising multiple vaults with the same name on the same remote server.
|
||||
- E2EE Algorithm
|
||||
- The cryptographic algorithm version used for end-to-end encryption. All synchronising devices must be configured with a compatible version (such as `V2` or `V1`).
|
||||
- Eden (Eden Chunks)
|
||||
- A performance optimisation where newly created chunks are held within the document until they stabilise, before graduating to independent chunks.
|
||||
- Fast Setup (Simple Fetch)
|
||||
- A simplified, automated initial synchronisation flow triggered when setting up subsequent devices or recovering a database. It bypasses the detailed step-by-step setup wizard dialogues, prompting the user with high-level data processing decisions and completing the initial download and local file scan in one continuous process.
|
||||
- Flag files (redflag.md, redflag2.md, redflag3.md)
|
||||
- Special Markdown files (or directories) placed at the root of the vault to stop the boot-up sequence or trigger recovery tasks. For instance, `redflag.md` suspends all processes, while `redflag2.md` (`flag_rebuild.md`) triggers a full database rebuild and `redflag3.md` (`flag_fetch.md`) discards the local database to fetch it again from the remote.
|
||||
- Garbage Collection (GC)
|
||||
- The process of identifying and purging unreferenced chunks (unused data) from local and remote databases to reclaim storage space.
|
||||
- Hatch (Hatch pane)
|
||||
- A dedicated troubleshooting and maintenance section in the plug-in settings, typically hidden behind a warning-labeled collapsible panel to prevent accidental misconfiguration. It contains diagnostic utilities, database reset controls, status reports, and advanced edge-case patches.
|
||||
- Hidden File Sync
|
||||
- The feature that synchronises files located in hidden directories (like `.obsidian`).
|
||||
- JWT Authentication
|
||||
- An experimental authentication option for CouchDB allowing secure token-based authentication instead of standard credentials. It requires a configured private key/secret, algorithm, expiration duration, subject, and key ID.
|
||||
- LiveSync
|
||||
- A very confusing term.
|
||||
- As a shortened form of `Self-hosted LiveSync`.
|
||||
- As the name of a synchronisation mode. This should be changed to `Continuous`, in contrast to `Periodic`.
|
||||
- livesync-serverpeer / webpeer
|
||||
- Pseudo-clients that assist in WebRTC peer-to-peer communication.
|
||||
- Metadata (File metadata)
|
||||
- A database document that stores properties of a file, including its filename, path, size, modification time, and references (hashes) of the chunks that comprise the file's content. Conflict state is carried by the surrounding PouchDB/CouchDB revision metadata rather than by a separate history field inside the file metadata document. In Self-hosted LiveSync, file metadata is stored separately from the actual file content to enable efficient synchronisation and versioning.
|
||||
- OneShot Sync
|
||||
- A single, immediate bidirectional synchronisation (pull then push) triggered on demand or on specific events, as opposed to continuous (live) replication.
|
||||
- Overwrite Server Data with This Device's Files
|
||||
- A maintenance operation (formerly known as `Rebuild everything`) that discards the remote database and reconstructs it by uploading all current local files as a fresh database, overwriting any remote changes.
|
||||
- Path Obfuscation
|
||||
- A privacy option that encrypts file paths and folder names on the remote server.
|
||||
- plug-in
|
||||
- We use the hyphenated form `plug-in` in user-facing messages and general documentation, while `plugin` may appear in codebase files, configuration settings, or technical contexts.
|
||||
- Signalling relay (P2P)
|
||||
- A Nostr-compatible WebSocket relay used for peer discovery and WebRTC connection negotiation. It does not store or transfer Vault contents. The project author operates a public relay as a best-effort convenience, and users can provide another compatible relay.
|
||||
- Remediation (maxMTimeForReflectEvents)
|
||||
- A recovery setting that restricts the propagation of changes from the database to local storage, ignoring any file events (such as accidental mass deletions) that occurred after a specified date and time.
|
||||
- Reset Synchronisation on This Device
|
||||
- A maintenance operation (formerly known as `Fetch everything`) that discards the local database and reconstructs it by downloading all data from the remote server.
|
||||
|
||||
#### Revision
|
||||
|
||||
A revision is a version of one PouchDB/CouchDB document. Concurrent changes can form a revision tree with more than one current branch.
|
||||
|
||||
Revision modifiers describe independent properties. More than one may apply to the same revision:
|
||||
|
||||
- **leaf**: Has no known child revision.
|
||||
- **winner**: Is the leaf selected by PouchDB/CouchDB as the current document.
|
||||
- **conflict**: Is another current leaf which was not selected as the winner.
|
||||
- **Vault-matching**: Represents the same file contents, or the same absent-file state, as the current Vault. More than one revision may match.
|
||||
- **displayed**: Is recorded by valid device-local file provenance as the branch represented in the Vault. A pending local edit may no longer match its bytes, but still extends this recorded branch.
|
||||
- **logically deleted**: Represents the absence of the file through a deletion marker. A logically deleted revision may also be a leaf, winner, conflict, or Vault-matching revision. An absent file retains no displayed provenance.
|
||||
|
||||
Avoid **live revision** in prose because it can ambiguously mean either a current leaf or a non-deleted revision. See [Independent revision properties](specs_conflict_resolution.md#independent-revision-properties) for the relationship between revision-tree roles, Vault state, and device-local provenance.
|
||||
|
||||
- Scram (Scram Switches)
|
||||
- Emergency controls in the settings that allow users to suspend file watching or database writes to prevent corruption.
|
||||
- Segmenter (Segmented-splitter)
|
||||
- A chunking method that divides files on semantic boundaries (such as paragraphs or sections) rather than arbitrary byte boundaries.
|
||||
- Self-hosted LiveSync
|
||||
- The name of this plug-in. `Self-hosted` is one word.
|
||||
- Setting Doctor (Config Doctor)
|
||||
- A diagnostic utility that checks for mismatches or suboptimal configurations, presenting users with ideal values and recommendation reasons to easily resolve issues during migration, configuration import, or general troubleshooting.
|
||||
- Setup URI
|
||||
- An encrypted representation of the plug-in's settings containing server configuration, which allows users to clone their configuration across devices securely using a passphrase.
|
||||
- Streaming replication (Stream-based replication)
|
||||
- A data transfer method that downloads database documents as a continuous stream of events. It is significantly faster than traditional chunk-by-chunk HTTP requests and is used during Fast Setup to retrieve remote metadata quickly.
|
||||
- Sync Mode
|
||||
- The replication trigger mechanism. Users can select from `On Events` (synchronising on local file changes), `Periodic and Events` (synchronising at fixed intervals as well as on events), or `LiveSync` (continuous, real-time synchronisation).
|
||||
- Synchronising devices
|
||||
- Devices which participate in the same synchronisation for a Vault. The term describes membership rather than current activity, so it includes offline and idle devices.
|
||||
- TURN Server (WebRTC P2P)
|
||||
- A Traversal Using Relays around NAT server used as an optional fallback to relay encrypted WebRTC traffic when strict NAT or firewall rules block a direct peer connection. It is distinct from the signalling relay.
|
||||
- Update Thinning (Batch database update)
|
||||
- An optimisation that groups multiple local file edits together over a short delay before committing them to the local database, reducing the number of database write operations.
|
||||
- WebRTC P2P (Peer-to-Peer)
|
||||
- A synchronisation method enabling direct communication between devices without a central server database.
|
||||
Project-specific meanings are defined separately in the
|
||||
[Project glossary](glossary.md).
|
||||
|
||||
Reference in New Issue
Block a user