mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-29 20:43:20 +00:00
Document published features and current technical behaviour
This commit is contained in:
1 parent
7d98f0c084
commit
2cfa4268cc
19 files changed
+241
-180
No files matched your search
@@ -51,7 +51,7 @@ Enter both client paths in the P2P profile's TURN server list:
|
|||||||
turn:turn.example.com:3478?transport=udp,turn:turn.example.com:3478?transport=tcp
|
turn:turn.example.com:3478?transport=udp,turn:turn.example.com:3478?transport=tcp
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `TURN_USERNAME` and `TURN_PASSWORD` as the TURN username and credential. Keep the normal `Automatic` ICE policy unless a future LiveSync release offers `TURN relay only` and the direct path needs to be excluded deliberately.
|
Use `TURN_USERNAME` and `TURN_PASSWORD` as the TURN username and credential. Keep the normal `Automatic` connection path unless the direct path needs to be excluded deliberately. Select `TURN relay only` under `Connection compatibility` to require the configured TURN route.
|
||||||
|
|
||||||
Both synchronising devices must be able to reach the server. Prove an explicit two-way `Replicate now` round trip on the intended networks before relying on the configuration.
|
Both synchronising devices must be able to reach the server. Prove an explicit two-way `Replicate now` round trip on the intended networks before relying on the configuration.
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Accepted — the user-facing controls will be introduced in stages. This record defines their boundaries before Commonlib settings and LiveSync interfaces are changed.
|
Accepted. The P2P message-size presets and connection-path choice are present
|
||||||
|
in current Self-hosted LiveSync 1.0.42 with Commonlib 0.2.2. The proposed
|
||||||
|
`Test TURN server` action and concise route diagnostics in the Obsidian
|
||||||
|
interface remain future work.
|
||||||
|
|
||||||
## Context
|
## Context
|
||||||
|
|
||||||
@@ -11,10 +14,12 @@ WebRTC connectivity depends on both devices, their browsers or embedded WebViews
|
|||||||
The current P2P transport has several relevant properties:
|
The current P2P transport has several relevant properties:
|
||||||
|
|
||||||
- Trystero supplies the Nostr signalling strategy and the browser-owned WebRTC connection.
|
- Trystero supplies the Nostr signalling strategy and the browser-owned WebRTC connection.
|
||||||
- Commonlib limits one RPC wire payload to 15,360 bytes so it remains below Trystero's own action-chunk boundary.
|
- Commonlib defaults to a 15,360-byte RPC wire payload limit, below Trystero's own action-chunk boundary; the presets below can lower it.
|
||||||
- Trystero supplies ordinary STUN servers and accepts an optional TURN server list with one username and credential.
|
- Manual TURN settings use one URL list, username, and credential. Managed preparation can supply multiple ICE server entries with their own credentials.
|
||||||
- ICE chooses a direct, server-reflexive, or TURN-relayed path automatically.
|
- ICE chooses a direct, server-reflexive, or TURN-relayed path automatically unless the profile selects `TURN relay only`.
|
||||||
- Commonlib can collect raw WebRTC statistics, but LiveSync does not yet present the selected candidate route in a concise diagnostic result.
|
- Commonlib can collect raw WebRTC statistics. The CLI reports the selected
|
||||||
|
candidate route, but the Obsidian interface does not yet present it in a
|
||||||
|
concise diagnostic result.
|
||||||
|
|
||||||
Issue reports suggest that reducing the application payload may improve some mobile and constrained-network paths. A VPN such as Tailscale may also turn an unreliable route into a reliable one. These observations are consistent with NAT, path-MTU, fragmentation, or intermediary behaviour, but they do not prove one universal cause. Browser WebRTC implementations retain responsibility for SCTP, DTLS, ICE, packetisation, congestion control, and retransmission.
|
Issue reports suggest that reducing the application payload may improve some mobile and constrained-network paths. A VPN such as Tailscale may also turn an unreliable route into a reliable one. These observations are consistent with NAT, path-MTU, fragmentation, or intermediary behaviour, but they do not prove one universal cause. Browser WebRTC implementations retain responsibility for SCTP, DTLS, ICE, packetisation, congestion control, and retransmission.
|
||||||
|
|
||||||
@@ -24,7 +29,7 @@ One low-level number cannot represent all of these concerns. Users need a small
|
|||||||
|
|
||||||
### Message-size presets
|
### Message-size presets
|
||||||
|
|
||||||
LiveSync will expose a `P2P message size` choice with four presets:
|
LiveSync exposes a `P2P message size` choice with four presets:
|
||||||
|
|
||||||
| Label | Maximum RPC wire payload | Intended use |
|
| Label | Maximum RPC wire payload | Intended use |
|
||||||
| ----------------------- | -----------------------: | ------------------------------------------------------------------------------- |
|
| ----------------------- | -----------------------: | ------------------------------------------------------------------------------- |
|
||||||
@@ -37,11 +42,11 @@ This value limits Commonlib RPC wire payloads before Trystero applies its own fr
|
|||||||
|
|
||||||
The bound applies to outgoing messages. A device which only lowers its own value still receives messages produced under the sender's value. The selected preset therefore belongs to the P2P profile and is included in an encrypted Setup URI for additional devices. A device which was configured earlier must be changed separately; the interface and troubleshooting guidance must state that the same conservative preset should be selected on every participating device. An absent key preserves the current 15,360-byte default.
|
The bound applies to outgoing messages. A device which only lowers its own value still receives messages produced under the sender's value. The selected preset therefore belongs to the P2P profile and is included in an encrypted Setup URI for additional devices. A device which was configured earlier must be changed separately; the interface and troubleshooting guidance must state that the same conservative preset should be selected on every participating device. An absent key preserves the current 15,360-byte default.
|
||||||
|
|
||||||
Automatic negotiation or fallback between presets is deferred. A failed ordered data channel may require connection replacement before a smaller retry can prove anything, and changing transport parameters during a replication session would broaden the lifecycle contract considerably. The first implementation remains explicit, stable for one room lifetime, and inspectable.
|
Automatic negotiation or fallback between presets is deferred. A failed ordered data channel may require connection replacement before a smaller retry can prove anything, and changing transport parameters during a replication session would broaden the lifecycle contract considerably. The implementation remains explicit, stable for one room lifetime, and inspectable.
|
||||||
|
|
||||||
### Connection path
|
### Connection path
|
||||||
|
|
||||||
LiveSync will expose a separate `Connection path` choice:
|
LiveSync exposes a separate `Connection path` choice:
|
||||||
|
|
||||||
- `Automatic` retains normal ICE selection and is the default.
|
- `Automatic` retains normal ICE selection and is the default.
|
||||||
- `TURN relay only` supplies `iceTransportPolicy: 'relay'` and prevents direct or server-reflexive candidates from being selected.
|
- `TURN relay only` supplies `iceTransportPolicy: 'relay'` and prevents direct or server-reflexive candidates from being selected.
|
||||||
@@ -81,11 +86,15 @@ Where the browser exposes the evidence, the result should report:
|
|||||||
- UDP, TCP, or TLS transport; and
|
- UDP, TCP, or TLS transport; and
|
||||||
- a bounded failure or inconclusive result.
|
- a bounded failure or inconclusive result.
|
||||||
|
|
||||||
Ordinary P2P diagnostics should later summarise the selected candidate pair as direct, server-reflexive, or relayed, with its transport. Raw `getStats()` output remains supporting evidence rather than the primary interface.
|
The proposed Obsidian P2P diagnostics should summarise the selected candidate
|
||||||
|
pair as direct, server-reflexive, or relayed, with its transport. The CLI's
|
||||||
|
candidate-route output does not provide this user-facing summary. Raw
|
||||||
|
`getStats()` output remains supporting evidence rather than the primary
|
||||||
|
interface.
|
||||||
|
|
||||||
### Placement and defaults
|
### Placement and defaults
|
||||||
|
|
||||||
These controls belong inside `P2P Configuration` under a `Connection compatibility` section. They do not require the repository-wide Advanced, Power User, or Edge Case modes. P2P itself remains a supported opt-in feature.
|
These controls appear inside `P2P Configuration` under a `Connection compatibility` section. They do not require the repository-wide Advanced, Power User, or Edge Case modes. P2P itself remains a supported opt-in feature.
|
||||||
|
|
||||||
Existing profiles retain the following defaults:
|
Existing profiles retain the following defaults:
|
||||||
|
|
||||||
@@ -161,7 +170,8 @@ A layer-4 TLS router could share one public address between distinct CouchDB and
|
|||||||
|
|
||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
The first implementation stage must add focused tests before production changes:
|
The following list records the original focused-test plan for the message-size
|
||||||
|
and connection-path controls. It remains useful as regression coverage:
|
||||||
|
|
||||||
- settings-schema defaults for absent keys;
|
- settings-schema defaults for absent keys;
|
||||||
- P2P connection-string and Setup URI round trips which retain both transport compatibility settings;
|
- P2P connection-string and Setup URI round trips which retain both transport compatibility settings;
|
||||||
|
|||||||
@@ -2,15 +2,17 @@
|
|||||||
date: 2026-10-24
|
date: 2026-10-24
|
||||||
commonlib-version: "0.2.0"
|
commonlib-version: "0.2.0"
|
||||||
self-hosted-livesync-version: "1.0.40"
|
self-hosted-livesync-version: "1.0.40"
|
||||||
status: accepted-unreleased
|
status: accepted
|
||||||
---
|
---
|
||||||
|
|
||||||
# Architectural Decision Record: Local File Save Completion and Batching
|
# Architectural Decision Record: Local File Save Completion and Batching
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Accepted on 2026-10-25. The package versions above identify the investigated
|
Accepted on 2026-10-25. The recovery contracts and LiveSync mode batching in
|
||||||
baseline, rather than a released implementation of this decision.
|
implementation-order steps 1–3 are present in current Self-hosted LiveSync
|
||||||
|
1.0.42 with Commonlib 0.2.2. The version fields above retain the investigated
|
||||||
|
baseline. Further same-path coalescing in step 4 remains a follow-up.
|
||||||
|
|
||||||
## Context
|
## Context
|
||||||
|
|
||||||
@@ -349,6 +351,9 @@ eliminating genuine concurrent-edit conflicts or as a confirmed fix for #1207.
|
|||||||
|
|
||||||
## Ownership and implementation order
|
## Ownership and implementation order
|
||||||
|
|
||||||
|
The list below records the implementation sequence. Steps 1–3 are published
|
||||||
|
in the current version line; the further coalescing in step 4 remains planned.
|
||||||
|
|
||||||
1. **Commonlib recovery:** event ownership, ordered snapshot persistence,
|
1. **Commonlib recovery:** event ownership, ordered snapshot persistence,
|
||||||
successful completion and failure propagation, finite flush boundaries, and
|
successful completion and failure propagation, finite flush boundaries, and
|
||||||
same-time content reconciliation. Add focused failing regressions before
|
same-time content reconciliation. Add focused failing regressions before
|
||||||
@@ -373,6 +378,11 @@ automation transaction API require a further design decision.
|
|||||||
|
|
||||||
## Verification required
|
## Verification required
|
||||||
|
|
||||||
|
The matrix below records the acceptance criteria for implementation steps 1–3
|
||||||
|
and remains useful for regression work. Publication in the current version line
|
||||||
|
does not extend the historical test results above to untested platforms or
|
||||||
|
automation workflows.
|
||||||
|
|
||||||
Use controlled promises at the manager and persistence boundaries for focused
|
Use controlled promises at the manager and persistence boundaries for focused
|
||||||
regressions, and real PouchDB tests for content and ancestry. The acceptance
|
regressions, and real PouchDB tests for content and ancestry. The acceptance
|
||||||
matrix is:
|
matrix is:
|
||||||
@@ -395,13 +405,13 @@ matrix is:
|
|||||||
| Old settings, mode changes, explicit opt-in, and settings import | Existing LiveSync mode users retain immediate saving until they choose batching. |
|
| Old settings, mode changes, explicit opt-in, and settings import | Existing LiveSync mode users retain immediate saving until they choose batching. |
|
||||||
| Incoming identical content, an edit, a deletion, or delete/recreate while waiting | Preserve genuine branches without extra conflicts or loss of local work. |
|
| Incoming identical content, an edit, a deletion, or delete/recreate while waiting | Preserve genuine branches without extra conflicts or loss of local work. |
|
||||||
|
|
||||||
Keep the existing E2E comparison between batching disabled, an ignored legacy
|
The original E2E plan compared batching disabled, an ignored legacy setting, and
|
||||||
setting, and explicitly enabled batching. Repeat both directions, manual
|
explicitly enabled batching in both directions, with manual synchronisation,
|
||||||
synchronisation, saved-snapshot restart, and controlled in-progress restart with
|
saved-snapshot restart, and controlled in-progress restart. Record the original
|
||||||
the fix. Record the original failure separately from repaired results; a pass
|
failure separately from repaired results; a pass with a different timestamp
|
||||||
with a different timestamp bucket or a test-only bundle is not verification of
|
bucket or a test-only bundle is not verification of the production fix. Keep
|
||||||
the production fix. Run platform-specific lifecycle checks before extending the
|
platform-specific lifecycle evidence bounded to the tested environments before
|
||||||
evidence to Windows or mobile.
|
extending conclusions to Windows or mobile.
|
||||||
|
|
||||||
## Alternatives and consequences
|
## Alternatives and consequences
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,16 @@
|
|||||||
date: 2026-10-17
|
date: 2026-10-17
|
||||||
commonlib-version: "0.1.42"
|
commonlib-version: "0.1.42"
|
||||||
self-hosted-livesync-version: "1.0.37"
|
self-hosted-livesync-version: "1.0.37"
|
||||||
status: unreleased
|
status: released
|
||||||
---
|
---
|
||||||
|
|
||||||
# Architectural Decision Record: Unicode Path Identity for CouchDB
|
# Architectural Decision Record: Unicode Path Identity for CouchDB
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Accepted on 2026-10-17. The feature remains unreleased. Local validation
|
Accepted on 2026-10-17. Unicode NFC path identity was released in Self-hosted
|
||||||
evidence and platform limits are recorded in the design document.
|
LiveSync 1.0.38 with Commonlib 0.1.42. Local validation evidence and platform
|
||||||
|
limits are recorded in the design document.
|
||||||
|
|
||||||
## Context
|
## Context
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
date: 2026-09-29
|
date: 2026-09-29
|
||||||
commonlib-version: "0.1.33"
|
commonlib-version: "0.1.33"
|
||||||
self-hosted-livesync-version: "1.0.32"
|
self-hosted-livesync-version: "1.0.32"
|
||||||
status: unreleased
|
status: released
|
||||||
---
|
---
|
||||||
|
|
||||||
# Configurable ID derivation
|
# Configurable ID derivation
|
||||||
@@ -21,12 +21,12 @@ including its passphrase-persistence correction at commit
|
|||||||
the `next` tag, provides the construction described here. It replaces the
|
the `next` tag, provides the construction described here. It replaces the
|
||||||
independent Chunk algorithm from the `0.1.32` prerelease without a
|
independent Chunk algorithm from the `0.1.32` prerelease without a
|
||||||
compatibility branch or a new settings version. Legacy ID generation remains
|
compatibility branch or a new settings version. Legacy ID generation remains
|
||||||
unchanged. LiveSync pins the published `0.1.33` package and its registry
|
unchanged. At that implementation baseline, LiveSync pinned the published
|
||||||
integrity in the lockfile.
|
`0.1.33` package and its registry integrity in the lockfile.
|
||||||
Its [Internal Metadata encryption design](https://github.com/vrtmrz/obsidian-livesync/blob/126d6eadb858a79a08ad7f600061e54fc8d31196/docs/design_docs/internal_metadata_encryption.md)
|
Its [Internal Metadata encryption design](https://github.com/vrtmrz/obsidian-livesync/blob/126d6eadb858a79a08ad7f600061e54fc8d31196/docs/design_docs/internal_metadata_encryption.md)
|
||||||
remains the basis for Properties encryption and CouchDB feature admission.
|
remains the basis for Properties encryption and CouchDB feature admission.
|
||||||
This document records an unreleased LiveSync feature. It does not select a
|
Independent ID derivation shipped in Self-hosted LiveSync 1.0.33. This document
|
||||||
plug-in release version.
|
retains the design and package baseline recorded above.
|
||||||
|
|
||||||
## Feasibility
|
## Feasibility
|
||||||
|
|
||||||
|
|||||||
@@ -10,40 +10,45 @@ This document uses the independent revision properties defined under
|
|||||||
[Revision](../glossary.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).
|
[Conflict resolution and revision provenance](../specs_conflict_resolution.md).
|
||||||
|
|
||||||
Document History can reconstruct an available historical revision from its
|
Before the current restoration implementation, Document History could
|
||||||
Chunks and write that content to the Vault through **Back to this revision**.
|
reconstruct an available historical revision from its Chunks and write that
|
||||||
The current action writes directly through the storage adapter. It does not
|
content to the Vault through **Back to this revision**. That action wrote
|
||||||
create a new Metadata revision, clear a logical deletion through a successor,
|
directly through the storage adapter. It did not create a new Metadata revision,
|
||||||
or record which database revision produced the restored Vault file.
|
clear a logical deletion through a successor, or record which database revision
|
||||||
|
produced the restored Vault file.
|
||||||
|
|
||||||
This leaves a logically deleted Metadata document at `deleted: true` after the
|
That left a logically deleted Metadata document at `deleted: true` after the
|
||||||
file has returned to the Vault. A later ordinary Vault save may create a
|
file had returned to the Vault. A later ordinary Vault save could create a
|
||||||
non-deleted successor, but restoration must not depend on an unrelated later
|
non-deleted successor, but restoration needed to succeed without depending on
|
||||||
file event.
|
an unrelated later file event.
|
||||||
|
|
||||||
The same action does not inspect or preserve revision-tree intent explicitly
|
Restoration does not resolve conflicts or provide a branch-aware history view.
|
||||||
when conflicts exist. Document History currently displays the ancestry of the
|
Document History displays the ancestry of the PouchDB winner; it does not
|
||||||
PouchDB winner. It does not display the complete revision tree or the ancestry
|
display the complete revision tree or the ancestry of every conflict leaf.
|
||||||
of every conflict leaf.
|
|
||||||
|
|
||||||
This design covers restoration of one readable historical revision of a normal
|
This design covers restoration of one readable historical revision of a normal
|
||||||
Vault file. It creates a new non-deleted successor revision, reflects that exact
|
Vault file. It creates a new non-deleted successor revision, reflects that exact
|
||||||
revision to the Vault, and leaves every other conflict branch available for the
|
revision to the Vault, and leaves every other conflict branch available for the
|
||||||
existing conflict workflow.
|
existing conflict workflow.
|
||||||
|
|
||||||
|
The current **Back to this revision** implementation writes that successor
|
||||||
|
revision, reflects the exact created revision to the Vault, and records it as
|
||||||
|
device-local provenance. The storage-only behaviour described above is the
|
||||||
|
pre-fix history.
|
||||||
|
|
||||||
## Evidence
|
## Evidence
|
||||||
|
|
||||||
A real-Obsidian exercise created a Markdown document, removed it through the
|
A real-Obsidian exercise before the current restoration implementation created
|
||||||
Vault API, and waited for LiveSync to store a logical-deletion successor. The
|
a Markdown document, removed it through the Vault API, and waited for LiveSync
|
||||||
Metadata retained all referenced Chunks, and Document History could reconstruct
|
to store a logical-deletion successor. The Metadata retained all referenced
|
||||||
the deleted content.
|
Chunks, and Document History could reconstruct the deleted content.
|
||||||
|
|
||||||
Selecting **Back to this revision** restored the file and its exact bytes to the
|
Selecting **Back to this revision** restored the file and its exact bytes to the
|
||||||
Vault. The local database nevertheless retained the same deleted current
|
Vault. The local database nevertheless retained the same deleted current
|
||||||
revision after file processing had settled. An additional ordinary Vault save
|
revision after file processing had settled. An additional ordinary Vault save
|
||||||
then created a new non-deleted successor. This demonstrates that content
|
then created a new non-deleted successor. This historical reproduction showed
|
||||||
reconstruction works and that the missing operation is the database-aware
|
that content reconstruction worked while the database-aware restoration step
|
||||||
restoration step.
|
was missing.
|
||||||
|
|
||||||
## Revision-tree decision
|
## Revision-tree decision
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
date: 2026-09-27
|
date: 2026-09-27
|
||||||
commonlib-version: "0.1.30"
|
commonlib-version: "0.1.30"
|
||||||
self-hosted-livesync-version: "1.0.32"
|
self-hosted-livesync-version: "1.0.32"
|
||||||
status: unreleased
|
status: released
|
||||||
---
|
---
|
||||||
|
|
||||||
# Internal Metadata encryption and remote feature changes
|
# Internal Metadata encryption and remote feature changes
|
||||||
|
|
||||||
This document defines the LiveSync integration of Commonlib's remote feature
|
This document defines the LiveSync integration of Commonlib's remote feature
|
||||||
contract and encrypted Metadata for Hidden File Sync and Customisation Sync.
|
contract and encrypted Metadata for Hidden File Sync and Customisation Sync.
|
||||||
It describes unreleased behaviour being implemented in this branch.
|
The implementation shipped in Self-hosted LiveSync 1.0.33; this document
|
||||||
|
retains its original design and implementation context.
|
||||||
|
|
||||||
Commonlib's companion `docs/remote-feature-compatibility.md` is the
|
Commonlib's companion `docs/remote-feature-compatibility.md` is the
|
||||||
source of truth for the wire document, identifiers, validation, and shared
|
source of truth for the wire document, identifiers, validation, and shared
|
||||||
@@ -159,11 +160,11 @@ after alignment. With the preference subsequently OFF, verify that Fast Fetch
|
|||||||
still decodes encrypted Metadata and preserves the remote feature declaration.
|
still decodes encrypted Metadata and preserves the remote feature declaration.
|
||||||
|
|
||||||
Keep the primary-language settings and troubleshooting guides, the
|
Keep the primary-language settings and troubleshooting guides, the
|
||||||
database-compatibility ADR, and Unreleased notes aligned with this behaviour.
|
database-compatibility ADR, and release notes consistent with this behaviour.
|
||||||
Keep the detailed shared protocol in Commonlib and link to it after publication;
|
Commonlib's companion document remains the source of truth for the shared
|
||||||
do not maintain another copy of its wire schema here. Translations are a separate
|
protocol; this document does not repeat its wire schema. Translations remain a
|
||||||
change. Update tested-version evidence when the implementation and its
|
separate change. The version fields above retain the original design baseline;
|
||||||
validation have been accepted.
|
add later tested-version evidence only when validation is recorded.
|
||||||
|
|
||||||
Related application contracts: [Replicator architecture](replicator_architecture.md),
|
Related application contracts: [Replicator architecture](replicator_architecture.md),
|
||||||
[Tweak compatibility](tweak_compatibility.md), and
|
[Tweak compatibility](tweak_compatibility.md), and
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
date: 2026-09-04
|
date: 2026-09-04
|
||||||
commonlib-version: "0.1.21"
|
commonlib-version: "0.1.21"
|
||||||
self-hosted-livesync-version: "1.0.24"
|
self-hosted-livesync-version: "1.0.24"
|
||||||
status: unreleased
|
status: released
|
||||||
---
|
---
|
||||||
|
|
||||||
# Path component length compatibility
|
# Path component length compatibility
|
||||||
@@ -11,9 +11,9 @@ status: unreleased
|
|||||||
|
|
||||||
File systems place limits on each file or folder name, rather than applying one
|
File systems place limits on each file or folder name, rather than applying one
|
||||||
common limit to an entire Vault-relative path. Those limits are also expressed
|
common limit to an entire Vault-relative path. Those limits are also expressed
|
||||||
in different units. Self-hosted LiveSync therefore treats 255 UTF-8 bytes as a
|
in different units. The warning shipped in Self-hosted LiveSync 1.0.26. It
|
||||||
focused Android and Linux compatibility warning, not as a universal definition
|
treats 255 UTF-8 bytes as a focused Android and Linux compatibility warning,
|
||||||
of a valid path.
|
not as a universal definition of a valid path.
|
||||||
|
|
||||||
## Basis for the 255-byte warning
|
## Basis for the 255-byte warning
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
date: 2026-09-16
|
date: 2026-09-16
|
||||||
commonlib-version: "0.1.25"
|
commonlib-version: "0.1.25"
|
||||||
self-hosted-livesync-version: "1.0.28"
|
self-hosted-livesync-version: "1.0.28"
|
||||||
status: unreleased
|
status: released
|
||||||
---
|
---
|
||||||
|
|
||||||
# TURN credentials in P2P connection settings
|
# TURN credentials in P2P connection settings
|
||||||
@@ -14,6 +14,9 @@ by acquiring temporary TURN credentials on the device before opening a P2P room.
|
|||||||
The [P2P transport compatibility ADR](../adr/2026_08_p2p_transport_compatibility.md)
|
The [P2P transport compatibility ADR](../adr/2026_08_p2p_transport_compatibility.md)
|
||||||
records the connection and persistence policy.
|
records the connection and persistence policy.
|
||||||
|
|
||||||
|
Managed Cloudflare TURN credentials shipped in Self-hosted LiveSync 1.0.29.
|
||||||
|
This document records the design and its remaining runtime verification limits.
|
||||||
|
|
||||||
LiveSync prepares a connection copy of `P2PSyncSetting`. Commonlib owns the room
|
LiveSync prepares a connection copy of `P2PSyncSetting`. Commonlib owns the room
|
||||||
lifecycle and consumes the resulting ICE settings. Service-specific HTTP and
|
lifecycle and consumes the resulting ICE settings. Service-specific HTTP and
|
||||||
validation remain under `src/integrations/`; Commonlib has no provider catalogue
|
validation remain under `src/integrations/`; Commonlib has no provider catalogue
|
||||||
|
|||||||
@@ -3,40 +3,42 @@ date: 2026-09-28
|
|||||||
commonlib-version: "0.1.33"
|
commonlib-version: "0.1.33"
|
||||||
feasibility-probe-version: "0.1.27"
|
feasibility-probe-version: "0.1.27"
|
||||||
self-hosted-livesync-version: "1.0.32"
|
self-hosted-livesync-version: "1.0.32"
|
||||||
status: implementing
|
status: released
|
||||||
---
|
---
|
||||||
|
|
||||||
# Time-bound Setup URIs
|
# Time-bound Setup URIs
|
||||||
|
|
||||||
## Purpose and status
|
## Purpose and status
|
||||||
|
|
||||||
Offer two modes when generating a [Setup URI](../glossary.md):
|
The published Obsidian generator offers two choices when creating a [Setup URI](../glossary.md):
|
||||||
|
|
||||||
- **Ephemeral**, selected by default, derives an effective passphrase from the
|
- **Time-bound** (the `ephemeral` derivation mode), selected by default,
|
||||||
entered passphrase and the current fixed time window.
|
derives an effective passphrase from the entered passphrase and the current
|
||||||
- **Persistent** uses the entered passphrase and the existing URI format
|
fixed time window.
|
||||||
unchanged. It also serves as the compatibility mode for older readers.
|
- **Compatible (no time limit)** (the `persistent` derivation mode) uses the
|
||||||
|
entered passphrase and the existing URI format unchanged. It also serves as
|
||||||
|
the compatibility mode for older readers.
|
||||||
|
|
||||||
The generation mode choice shows the exact time until which an Ephemeral URI
|
The Time-bound choice shows the exact time until which the URI can be opened
|
||||||
can be opened through the ordinary reader. Import still requires only the URI and
|
through the ordinary reader. Import still requires only the URI and the entered
|
||||||
the entered passphrase. Neither the mode nor a timestamp is stored in the URI.
|
passphrase. Neither the mode nor a timestamp is stored in the URI.
|
||||||
|
|
||||||
The design is technically feasible with the existing encryption primitives.
|
Both URI availability choices shipped in Self-hosted LiveSync 1.0.33. The
|
||||||
An executable protocol probe passes 22 cases against Commonlib 0.1.27 and
|
initial executable protocol probe passed 22 cases against Commonlib 0.1.27 and
|
||||||
octagonal-wheels 0.1.54. The implementation was first published as Commonlib 0.1.32
|
octagonal-wheels 0.1.54. The implementation was first published as Commonlib
|
||||||
on the npm `next` tag. LiveSync now pins Commonlib 0.1.33 from that tag in its npm
|
0.1.32 on the npm `next` tag. Current Self-hosted LiveSync 1.0.42 uses Commonlib
|
||||||
dependency and independent Deno tool imports. A mobile performance bound remains
|
0.2.2. A mobile performance bound remains outstanding.
|
||||||
outstanding.
|
|
||||||
|
|
||||||
This document records the proposed key derivation and integration contract. The
|
This document records the protocol and the integration plan used for the
|
||||||
companion probe demonstrates them without changing an application entry point.
|
published feature. The companion probe remains a standalone design check; it
|
||||||
|
does not exercise an application entry point.
|
||||||
|
|
||||||
## Scope
|
## Scope
|
||||||
|
|
||||||
The first version offers Ephemeral and Persistent only. Ephemeral uses one
|
The published protocol offers the Ephemeral and Persistent modes only.
|
||||||
fixed seven-day window shared by every implementation. Arbitrary start dates,
|
Ephemeral uses one fixed seven-day window shared by every implementation.
|
||||||
custom end dates, selectable window lengths, and rolling seven-day lifetimes
|
Arbitrary start dates, custom end dates, selectable window lengths, and rolling
|
||||||
are outside this version.
|
seven-day lifetimes are outside this version.
|
||||||
|
|
||||||
Keep the current settings filtering, remote profiles, main and P2P selections,
|
Keep the current settings filtering, remote profiles, main and P2P selections,
|
||||||
and short/full export variants. Time binding affects opening the exported
|
and short/full export variants. Time binding affects opening the exported
|
||||||
@@ -255,15 +257,16 @@ separately shared message.
|
|||||||
## Ownership and compatibility
|
## Ownership and compatibility
|
||||||
|
|
||||||
Commonlib owns preparation of exported settings, the time-window calculation,
|
Commonlib owns preparation of exported settings, the time-window calculation,
|
||||||
passphrase derivation, format parsing, and dual-candidate decoding. Make these
|
passphrase derivation, format parsing, and dual-candidate decoding. These
|
||||||
changes in the Commonlib repository. LiveSync must consume a validated packed
|
changes were made in the Commonlib repository. LiveSync consumes the reviewed
|
||||||
artefact and then an exact reviewed package version, following
|
Commonlib package, following
|
||||||
[the Commonlib dependency workflow](../../devs.md#commonlib-dependency).
|
[the Commonlib dependency workflow](../../devs.md#commonlib-dependency).
|
||||||
|
|
||||||
Preserve the existing positional encoder API. Its third and fourth arguments
|
The implementation preserves the existing positional encoder API. Its third
|
||||||
already mean properties to remove and whether to omit default values. Add a
|
and fourth arguments retain their meanings: properties to remove and whether
|
||||||
separate encoder, provisionally `encodeTimeBoundSetupURI`, with an options
|
to omit default values. It adds a separate `encodeTimeBoundSetupURI` encoder
|
||||||
object containing the mode and the existing export options. Its result is:
|
with an options object containing the mode and the existing export options.
|
||||||
|
Its result is:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
type TimeBoundSetupURIResult = {
|
type TimeBoundSetupURIResult = {
|
||||||
@@ -272,27 +275,27 @@ type TimeBoundSetupURIResult = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
The new encoder defaults to Ephemeral. Preserve the old encoder's legacy
|
The new encoder defaults to Ephemeral. The old encoder retains its legacy
|
||||||
behaviour for callers which have not migrated. Extend
|
behaviour for callers which have not migrated. The updated
|
||||||
`decodeSettingsFromSetupURI` to try both candidates for `%$` while retaining its
|
`decodeSettingsFromSetupURI` tries both candidates for `%$` while retaining its
|
||||||
settings return contract and historical format handling. Persistent generation
|
settings return contract and historical format handling. Persistent generation
|
||||||
through the new API delegates to the old encoder. Time injection belongs in
|
through the new API delegates to the old encoder. Time injection remains in
|
||||||
internal test seams, not an import option exposed to users.
|
internal test seams, not an import option exposed to users.
|
||||||
|
|
||||||
| Surface | Required work |
|
| Surface | Published integration |
|
||||||
| ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| [Obsidian generation](../../src/serviceFeatures/setupObsidian/setupUri.ts) | Reuse the passphrase and copy dialogues, add a mode choice with the exact current window end, and use the new encoder for all three copy variants and the copy event. Preserve each variant's export filters. |
|
| [Obsidian generation](../../src/serviceFeatures/setupObsidian/setupUri.ts) | Reuses the passphrase and copy dialogues, presents the mode choice and exact current window end, and uses the encoder for all copy variants and the copy event while preserving each variant's export filters. |
|
||||||
| [Obsidian import](../../src/modules/features/SetupWizard/dialogs/UseSetupURI.svelte) | Consume the updated decoder and retain one authentication failure message. The existing prefix check indicates URI shape, not successful authentication. |
|
| [Obsidian import](../../src/modules/features/SetupWizard/dialogs/UseSetupURI.svelte) | Consumes the updated decoder and retains one authentication failure message. The existing prefix check indicates URI shape, not successful authentication. |
|
||||||
| [Protocol handler](../../src/serviceFeatures/setupObsidian/setupProtocol.ts) | Keep the existing `settings` reconstruction; test encoded delimiters for both modes. |
|
| [Protocol handler](../../src/serviceFeatures/setupObsidian/setupProtocol.ts) | Retains the existing `settings` reconstruction; encoded delimiters remain part of protocol validation for both modes. |
|
||||||
| [CLI setup](../../src/apps/cli/commands/runCommand.ts) | Consume the updated decoder and leave settings unchanged after any rejection. |
|
| [CLI setup](../../src/apps/cli/commands/runCommand.ts) | Uses the updated decoder and leaves settings unchanged after a rejection. |
|
||||||
| [WebPeer generator](../../src/apps/webpeer/src/P2PCheckSetup.ts) | Choose a mode explicitly and return availability to its result UI; keep Ephemeral as the default. |
|
| [WebPeer generator](../../src/apps/webpeer/src/P2PCheckSetup.ts) | Explicitly selects Time-bound mode and returns availability to its result UI; this generator does not offer a Persistent choice. |
|
||||||
| [Setup utility](../../utils/setup/generate_setup_uri.ts) | Add an explicit mode input, default to Ephemeral, and return/print the end time. Persistent is an explicit choice for durable provisioning output. |
|
| [Setup utility](../../utils/setup/generate_setup_uri.ts) | Accepts an explicit mode, defaults to Time-bound, and returns or prints the end time. Persistent is selected for durable provisioning output. |
|
||||||
| [Setup utility package facade](../../utils/setup/livesync-commonlib.ts) | Update its independent Commonlib pin and associated lockfiles; updating the root npm dependency alone is insufficient. |
|
| [Setup utility package facade](../../utils/setup/livesync-commonlib.ts) | Retains its independent Commonlib pin and associated lockfiles, separate from the root npm dependency. |
|
||||||
|
|
||||||
The Fly.io wrapper delegates to the setup utility and should inherit the same
|
The Fly.io wrapper delegates to the setup utility and inherits the same
|
||||||
contract. All maintained generators must migrate explicitly before this
|
contract. The initial plan required each maintained generator to select a mode
|
||||||
feature is described as the default across applications. Non-interactive
|
explicitly. Non-interactive automation which needs a durable URI selects
|
||||||
automation which needs a durable URI must select Persistent.
|
Persistent.
|
||||||
|
|
||||||
WebPeer hides an Ephemeral URI and disables its copy and additional-device
|
WebPeer hides an Ephemeral URI and disables its copy and additional-device
|
||||||
actions after the window ends. Its connection monitor remains available for a
|
actions after the window ends. Its connection monitor remains available for a
|
||||||
@@ -309,8 +312,9 @@ The assessed, unchanged Commonlib 0.1.27 decoder opens Persistent with the
|
|||||||
entered passphrase and rejects Ephemeral with that same passphrase. Persistent
|
entered passphrase and rejects Ephemeral with that same passphrase. Persistent
|
||||||
compatibility means compatibility with readers which already support the
|
compatibility means compatibility with readers which already support the
|
||||||
ordinary generated `%$` representation; it does not add that representation
|
ordinary generated `%$` representation; it does not add that representation
|
||||||
to still older readers. Historical supported versions and their settings
|
to still older readers. This design does not establish compatibility with every
|
||||||
schemas still need compatibility fixtures before rollout.
|
historical reader or settings schema; compatibility fixtures are needed before
|
||||||
|
making broader claims about them.
|
||||||
|
|
||||||
Keep the original raw-passphrase behaviour of existing URIs. They are
|
Keep the original raw-passphrase behaviour of existing URIs. They are
|
||||||
indistinguishable from newly generated Persistent URIs to the updated reader.
|
indistinguishable from newly generated Persistent URIs to the updated reader.
|
||||||
@@ -358,68 +362,72 @@ All 22 cases passed:
|
|||||||
and raw-passphrase candidates;
|
and raw-passphrase candidates;
|
||||||
- the deliberate limitation that clock rollback reproduces an old key.
|
- the deliberate limitation that clock rollback reproduces an old key.
|
||||||
|
|
||||||
This demonstrates the proposed mechanism and baseline interoperability, not
|
The probe demonstrates feasibility and baseline interoperability. Application
|
||||||
completed application support, formal mode indistinguishability, or a mobile
|
integration is recorded above; the probe does not establish formal mode
|
||||||
latency bound. The present encryption API may perform two PBKDF2 derivations
|
indistinguishability or a mobile latency bound. The encryption API may perform
|
||||||
on a cold import. Do not infer production performance from this small probe,
|
two PBKDF2 derivations on a cold import. Do not infer production performance
|
||||||
whose operations can reuse the dependency's in-memory key cache.
|
from this small probe, whose operations can reuse the dependency's in-memory
|
||||||
|
key cache.
|
||||||
|
|
||||||
Implementation validation must cover Commonlib unit and packed-package tests,
|
The original implementation validation plan covered Commonlib unit and
|
||||||
plus shared fixed-input protocol vectors across consumers. Add targeted LiveSync
|
packed-package tests, plus shared fixed-input protocol vectors across consumers.
|
||||||
tests for the generation metadata, cancellation, a window change during mode
|
It called for targeted LiveSync tests of generation metadata, cancellation, a
|
||||||
selection, encoded deep links, and rejected imports without settings writes. Extend CLI, WebPeer,
|
window change during mode selection, encoded deep links, and rejected imports
|
||||||
and Deno setup-tool round trips, including their Persistent selection.
|
without settings writes, alongside CLI, WebPeer, and Deno setup-tool round trips
|
||||||
|
for both modes.
|
||||||
|
|
||||||
Then run the required LiveSync checks, unit suite, and production build, one
|
The plan also called for the LiveSync checks, unit suite, and production build,
|
||||||
broad process at a time with `NODE_OPTIONS=--max-old-space-size=3072` and bounded
|
one broad process at a time with `NODE_OPTIONS=--max-old-space-size=3072` and
|
||||||
test workers. Use the existing focused real-Obsidian Setup URI workflow for
|
bounded test workers. It used the focused real-Obsidian Setup URI workflow for
|
||||||
copy/paste, deep-link import, cancellation, and successful setup. Verify
|
copy/paste, deep-link import, cancellation, and successful setup. Selection-
|
||||||
selection-boundary handling with an injected test clock and mobile behaviour on a
|
boundary handling was to use an injected test clock; mobile behaviour requires
|
||||||
supported runtime; do not change the host's system clock. No remote database
|
a supported runtime and must not change the host's system clock. Protocol tests
|
||||||
service is needed for the protocol tests themselves.
|
do not require a remote database service.
|
||||||
|
|
||||||
There is no identified blocker in the Time-bound URI protocol. The Commonlib
|
The original protocol assessment found no blocker in the Time-bound URI
|
||||||
candidate based on 0.1.31 passed its type, unit, boundary, release-process,
|
protocol. The Commonlib candidate based on 0.1.31 passed its type, unit,
|
||||||
and packed-package gates before the 0.1.32 release. A clean `npm ci` against
|
boundary, release-process, and packed-package gates before the 0.1.32 release. A
|
||||||
the published 0.1.32 artefact and the frozen Deno tool lock resolve the same
|
clean `npm ci` against the published 0.1.32 artefact and the frozen Deno tool
|
||||||
registry integrity. LiveSync passes its source checks, production build, and
|
lock resolved the same registry integrity. In the original implementation
|
||||||
1,034 unit tests on a local stack with [PR #1222](https://github.com/vrtmrz/obsidian-livesync/pull/1222).
|
baseline, LiveSync passed its source checks, production build, and 1,034 unit
|
||||||
The two CLI installer tests need a runner which permits child processes; both
|
tests on a local stack with [PR #1222](https://github.com/vrtmrz/obsidian-livesync/pull/1222).
|
||||||
pass under normal process permissions. The Deno setup-tool suite, CLI setup
|
The two CLI installer tests needed a runner which permits child processes; both
|
||||||
|
passed under normal process permissions. The Deno setup-tool suite, CLI setup
|
||||||
and file-operation contract, and WebPeer browser tests passed before stacking.
|
and file-operation contract, and WebPeer browser tests passed before stacking.
|
||||||
|
|
||||||
Focused real-Obsidian generation checks pass on desktop and emulated mobile,
|
The recorded real-Obsidian generation checks passed on desktop and emulated mobile,
|
||||||
including the displayed Time-bound end, Compatible output, and mobile touch
|
including the displayed Time-bound end, Compatible output, and mobile touch
|
||||||
targets. A two-device CouchDB workflow now passes on the local stack: the
|
targets. A two-device CouchDB workflow passed on the local stack: the
|
||||||
provisioning tool creates a generation 12 database, the first device generates
|
provisioning tool created a generation 12 database, the first device generated
|
||||||
a Time-bound Setup URI after declaring its required generation 13 feature, and
|
a Time-bound Setup URI after declaring its required generation 13 feature, and
|
||||||
the second device imports it. An ordinary note completes a round trip, and a
|
the second device imported it. An ordinary note completed a round trip, and a
|
||||||
hidden snippet synchronises. The separate real-Obsidian tests for live remote
|
hidden snippet synchronised. The separate real-Obsidian tests for live remote
|
||||||
feature changes, internal Metadata migration, and a percent-prefixed E2EE
|
feature changes, internal Metadata migration, and a percent-prefixed E2EE
|
||||||
passphrase also pass with published Commonlib 0.1.32. Unit and protocol tests
|
passphrase also passed with published Commonlib 0.1.32. Unit and protocol tests
|
||||||
cover window boundaries and preserve the existing distinction between an empty
|
covered window boundaries and preserved the existing distinction between an
|
||||||
passphrase and cancellation. The WebPeer browser test confirms that its monitor
|
empty passphrase and cancellation. The WebPeer browser test confirmed that its
|
||||||
remains available after the URI window ends for a device which has already
|
monitor remained available after the URI window ended for a device which had
|
||||||
imported the URI.
|
already imported the URI.
|
||||||
|
|
||||||
The current Commonlib 0.1.33 integration includes the merged host changes from
|
The Commonlib 0.1.33 integration included the merged host changes from
|
||||||
PR #1222 and PR #1225. npm 10 and normal clean installations preserve the lockfile;
|
PR #1222 and PR #1225. At that baseline, npm 10 and normal clean installations
|
||||||
source checks, the production build, 1,064 unit tests, and ten Deno setup-tool
|
preserved the lockfile; source checks, the production build, 1,064 unit tests,
|
||||||
tests pass. Both URI modes preserve ID recovery and explicit legacy ID selection.
|
and ten Deno setup-tool tests passed. Both URI modes preserved ID recovery and
|
||||||
|
explicit legacy ID selection.
|
||||||
|
|
||||||
Real Obsidian tests cover independent ID keys through Time-bound, Compatible,
|
Recorded real-Obsidian tests covered independent ID keys through Time-bound,
|
||||||
and QR setup, encrypted local persistence, natural restarts of both devices,
|
Compatible, and QR setup, encrypted local persistence, natural restarts of both
|
||||||
and bidirectional note transfers with stable document and Chunk IDs. Incorrect
|
devices, and bidirectional note transfers with stable document and Chunk IDs.
|
||||||
passphrases and past-window URIs leave runtime and persisted settings unchanged.
|
Incorrect passphrases and past-window URIs left runtime and persisted settings
|
||||||
The past clock belongs to an isolated fixture worker, not Obsidian or the host.
|
unchanged. The past clock belonged to an isolated fixture worker, not Obsidian
|
||||||
CouchDB tests also cover a custom ID source and recovery code, rejection of
|
or the host. CouchDB tests also covered a custom ID source and recovery code,
|
||||||
incompatible document keys before remote writes, and the Doctor's decline,
|
rejection of incompatible document keys before remote writes, and the Doctor's
|
||||||
reminder, dismissal, and later acceptance paths. The detailed commands and the
|
decline, reminder, dismissal, and later acceptance paths. The detailed commands,
|
||||||
remaining published-artefact and physical-device checks are recorded in the
|
remaining published-artefact checks, and physical-device checks are recorded in the
|
||||||
[real Obsidian test guide](../../test/e2e-obsidian/README.md#combined-setup-and-security-regression-checks).
|
[real Obsidian test guide](../../test/e2e-obsidian/README.md#combined-setup-and-security-regression-checks).
|
||||||
|
|
||||||
Compatible preserves the URI encryption format; each receiving client must
|
Compatible preserves the URI encryption format; each receiving client must
|
||||||
still support the shared settings and the remote's declared features. The host
|
still support the shared settings and the remote's declared features. The host
|
||||||
compatibility checks from PR #1222 remain necessary. These results do not
|
compatibility checks from PR #1222 remain necessary. These results do not
|
||||||
establish a mobile performance bound. The first implementation changes only
|
establish a mobile performance bound. The initial implementation changed only
|
||||||
primary-language resources; translation changes require separate scope.
|
primary-language resources; translation changes remain a separate scope.
|
||||||
@@ -2,15 +2,16 @@
|
|||||||
date: 2026-10-17
|
date: 2026-10-17
|
||||||
commonlib-version: "0.1.42"
|
commonlib-version: "0.1.42"
|
||||||
self-hosted-livesync-version: "1.0.37"
|
self-hosted-livesync-version: "1.0.37"
|
||||||
status: unreleased
|
status: released
|
||||||
---
|
---
|
||||||
|
|
||||||
# Tweak compatibility and recovery
|
# Tweak compatibility and recovery
|
||||||
|
|
||||||
This document describes the compatibility and recovery contract, including
|
This document describes the compatibility and recovery contract introduced
|
||||||
unreleased changes after Self-hosted LiveSync 1.0.37 using Commonlib 0.1.42.
|
after the Self-hosted LiveSync 1.0.37 and Commonlib 0.1.42 baseline recorded
|
||||||
Commonlib owns the interpretation of synchronisation settings; LiveSync owns
|
above. The current assessment is included in Self-hosted LiveSync 1.0.42 with
|
||||||
the dialogues and operations which consume that result.
|
Commonlib 0.2.2. Commonlib owns the interpretation of synchronisation settings;
|
||||||
|
LiveSync owns the dialogues and operations which consume that result.
|
||||||
|
|
||||||
## Shared assessment
|
## Shared assessment
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
date: 2026-10-19
|
date: 2026-10-19
|
||||||
commonlib-version: "0.1.43"
|
commonlib-version: "0.1.43"
|
||||||
self-hosted-livesync-version: "1.0.38"
|
self-hosted-livesync-version: "1.0.38"
|
||||||
status: unreleased
|
status: released
|
||||||
---
|
---
|
||||||
|
|
||||||
# Unicode path identity
|
# Unicode path identity
|
||||||
@@ -17,8 +17,10 @@ Commonlib's [consumer contract](https://github.com/vrtmrz/livesync-commonlib/blo
|
|||||||
defines the shared package boundary.
|
defines the shared package boundary.
|
||||||
|
|
||||||
NFC identity shipped in Self-hosted LiveSync `1.0.38` with Commonlib `0.1.42`.
|
NFC identity shipped in Self-hosted LiveSync `1.0.38` with Commonlib `0.1.42`.
|
||||||
The deletion handling in reconstruction below uses Commonlib `0.1.43` and
|
Conflict-aware deletion handling during reconstruction was added separately
|
||||||
remains unreleased in Self-hosted LiveSync.
|
and is included in current Commonlib `0.2.2`, used by Self-hosted LiveSync
|
||||||
|
`1.0.42`. This later handling is distinct from the initial NFC identity
|
||||||
|
release.
|
||||||
|
|
||||||
## Scope
|
## Scope
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
## The design document of the journal sync
|
## The design document of the journal sync
|
||||||
|
|
||||||
|
Historical design: this is the first Journal Sync design. Its original transfer sequence and discussion of possible storage backends are retained as history. For the maintained pipeline and storage-adapter design, read [Journal Replicator 2nd Edition](design_docs_of_journalsync_2nd.md) and the [Replicator architecture](design_docs/replicator_architecture.md). Use [Object Storage Setup](setup_object_storage.md) for supported client setup. A possible backend discussed here is not evidence that an adapter is available in the current release.
|
||||||
|
|
||||||
Original title: Synchronise without CouchDB
|
Original title: Synchronise without CouchDB
|
||||||
|
|
||||||
### Goal
|
### Goal
|
||||||
@@ -47,4 +49,4 @@ This implementation replaces the synchronisation performed by CouchDB. Therefore
|
|||||||
|
|
||||||
### Consideration and Conclusion
|
### Consideration and Conclusion
|
||||||
|
|
||||||
This design offers a novel approach to journal synchronisation without relying on CouchDB. It leverages PouchDB's journaling capabilities and leverages simple server-side storage for efficient data exchange. Hence, the new design could be said to have gotten a broader outlook.
|
This design offers a novel approach to journal synchronisation without relying on CouchDB. It leverages PouchDB's journaling capabilities and leverages simple server-side storage for efficient data exchange. Hence, the new design could be said to have gotten a broader outlook.
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
# The design document of remote configuration management
|
# The design document of remote configuration management
|
||||||
|
|
||||||
|
## Implementation status
|
||||||
|
|
||||||
|
This document describes the profile catalogue and its runtime projections as used by Self-hosted LiveSync 1.0.42 with Commonlib 0.2.2. Commonlib owns profile migration, activation, and protected settings persistence. The [Replicator architecture](design_docs/replicator_architecture.md) and [P2P service lifecycle decision](adr/2026_08_replicator_capabilities_02_p2p_service_lifecycle.md) describe the separate P2P service boundary.
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
- Allow us to manage multiple remote connections in a single vault.
|
- Allow us to manage multiple remote connections in a single vault.
|
||||||
@@ -33,7 +37,9 @@ Once multiple remotes of the same type became desirable, the previous model no l
|
|||||||
The current settings now have two layers for remote configuration.
|
The current settings now have two layers for remote configuration.
|
||||||
|
|
||||||
1. A stored collection of named remotes.
|
1. A stored collection of named remotes.
|
||||||
2. One active remote projected into the legacy flat settings fields.
|
2. One active main remote projected into the legacy flat settings fields.
|
||||||
|
|
||||||
|
The P2P service also has its own selected profile, recorded by `P2P_ActiveRemoteConfigurationId`. This permits the P2P service to use a selected P2P profile alongside a CouchDB or Object Storage main remote; it does not introduce a second main remote.
|
||||||
|
|
||||||
This means the replication and database layers can continue to read the effective remote from the existing settings fields, while the settings dialogue and migration logic can manage many stored remotes.
|
This means the replication and database layers can continue to read the effective remote from the existing settings fields, while the settings dialogue and migration logic can manage many stored remotes.
|
||||||
|
|
||||||
@@ -54,6 +60,7 @@ type RemoteConfiguration = {
|
|||||||
type RemoteConfigurations = {
|
type RemoteConfigurations = {
|
||||||
remoteConfigurations: Record<string, RemoteConfiguration>;
|
remoteConfigurations: Record<string, RemoteConfiguration>;
|
||||||
activeConfigurationId: string;
|
activeConfigurationId: string;
|
||||||
|
P2P_ActiveRemoteConfigurationId: string;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -116,7 +123,11 @@ Therefore:
|
|||||||
- Import trusts the supplied connection string as-is after parsing.
|
- Import trusts the supplied connection string as-is after parsing.
|
||||||
- We should regard exported connection strings as sensitive information, much like Setup URI or a credentials-bearing configuration file.
|
- We should regard exported connection strings as sensitive information, much like Setup URI or a credentials-bearing configuration file.
|
||||||
|
|
||||||
The `isEncrypted` field is currently reserved for future expansion. At present, the connection string itself is stored plainly inside the settings data, in the same sense that the effective runtime configuration can contain usable remote credentials.
|
The `isEncrypted` field identifies an encrypted profile URI in persisted settings. When settings are saved with configuration encryption enabled, Commonlib encrypts the profile URIs and records `isEncrypted: true`. Loading protected settings decrypts the URIs into the runtime settings and clears that runtime flag before profile activation. The runtime settings and the persisted representation therefore have different purposes.
|
||||||
|
|
||||||
|
Protection depends on the configured settings-passphrase policy and a usable key. A plaintext configuration is not made confidential by the presence of the field alone. Consult [Encrypting sensitive configuration items](settings.md#encrypting-sensitive-configuration-items) for that policy.
|
||||||
|
|
||||||
|
Clipboard export serialises the usable connection string. Treat that exported value as sensitive even when its saved profile URI is encrypted at rest; storage protection does not encrypt the clipboard representation.
|
||||||
|
|
||||||
### Migration strategy
|
### Migration strategy
|
||||||
|
|
||||||
@@ -129,7 +140,7 @@ Rules:
|
|||||||
- If no remote list exists and the legacy fields contain a Peer-to-Peer configuration, create `legacy-p2p`.
|
- If no remote list exists and the legacy fields contain a Peer-to-Peer configuration, create `legacy-p2p`.
|
||||||
- If more than one legacy remote is populated, create all possible entries and select the active one according to `remoteType`.
|
- If more than one legacy remote is populated, create all possible entries and select the active one according to `remoteType`.
|
||||||
|
|
||||||
This migration is intentionally additive. It does not remove the flat fields because they remain necessary as the active runtime projection.
|
This migration is intentionally additive. It does not remove the flat fields because they remain necessary as the active runtime projection. A migrated legacy P2P profile also initialises the separate P2P selection. Loading an existing profile catalogue does not unconditionally replace an intentionally empty P2P selection.
|
||||||
|
|
||||||
### Normalisation and application paths
|
### Normalisation and application paths
|
||||||
|
|
||||||
@@ -190,7 +201,7 @@ The feature should be tested from four viewpoints.
|
|||||||
|
|
||||||
## Outlook
|
## Outlook
|
||||||
|
|
||||||
Import/export configuration strings should also be encrypted in the future, but this is a separate feature that can be added on top of the current design.
|
A separately encrypted representation for clipboard import and export remains a possible extension. Encryption of profile URIs in persisted settings is already implemented as described above.
|
||||||
|
|
||||||
## Consideration and conclusion
|
## Consideration and conclusion
|
||||||
|
|
||||||
@@ -203,4 +214,4 @@ Its core idea is modest but effective.
|
|||||||
- Project it into the legacy settings for runtime use.
|
- Project it into the legacy settings for runtime use.
|
||||||
- Normalise every imported settings object through the same path.
|
- Normalise every imported settings object through the same path.
|
||||||
|
|
||||||
This keeps the implementation understandable and migration-friendly. It also opens the door for future work, such as encrypted per-remote storage, richer remote metadata, or remote-scoped options, without forcing another large redesign of how remotes are represented.
|
This keeps the implementation understandable and migration-friendly. It also opens the door for future work, such as richer remote metadata or remote-scoped options, without forcing another large redesign of how remotes are represented.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Sharing `Tweak values`
|
# Sharing `Tweak values`
|
||||||
|
|
||||||
NOTE: This is the planned feature design document. This is planned, but not be implemented now (v0.23.3). This has not reached the design freeze and will be added to from time to time.
|
Historical design: this document records the original proposal written for v0.23.3. Tweak sharing and compatibility assessment are implemented in published releases. Use [Tweak compatibility and recovery](design_docs/tweak_compatibility.md) for the maintained contract, and [Settings](settings.md) for the available controls. The proposal and test plan below are retained as design history; they do not define the current behaviour.
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
@@ -52,4 +52,4 @@ B: On the setting dialogue.
|
|||||||
- However, this might be an essential feature. Further efforts are desired.
|
- However, this might be an essential feature. Further efforts are desired.
|
||||||
|
|
||||||
### Consideration and Conclusion
|
### Consideration and Conclusion
|
||||||
To be described after implemented, tested, and, released.
|
The published implementation has evolved beyond this proposal, including classification of compatible differences and automatic alignment where configured. Its current decisions, recovery requirements, and remaining limitations are recorded in [Tweak compatibility and recovery](design_docs/tweak_compatibility.md). The original proposal does not establish that every item in its test plan was implemented unchanged.
|
||||||
@@ -19,10 +19,11 @@ The command and view are registered only when developer tools are enabled. Disab
|
|||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| Settings lifecycle | Automatic | Read-only | Exposes the seven synchronisation choices as typed observations and, for a genuinely new Vault, compares the selected recommendations with Commonlib's new-Vault contract. Existing-Vault setting preservation remains an automated migration and `settings-ui` E2E responsibility. |
|
| Settings lifecycle | Automatic | Read-only | Exposes the seven synchronisation choices as typed observations and, for a genuinely new Vault, compares the selected recommendations with Commonlib's new-Vault contract. Existing-Vault setting preservation remains an automated migration and `settings-ui` E2E responsibility. |
|
||||||
| Compatibility review boundary | Guided | Device-local state | Observes the current dedicated compatibility controller and opens its actual review action. The Harness does not restore Change Log acknowledgement, `lastReadUpdates`, or a separate manual Pass or Fail result. |
|
| Compatibility review boundary | Guided | Device-local state | Observes the current dedicated compatibility controller and opens its actual review action. The Harness does not restore Change Log acknowledgement, `lastReadUpdates`, or a separate manual Pass or Fail result. |
|
||||||
| P2P composition | Automatic | Read-only | Confirms that the live P2P result resolves one replicator bound to the active Obsidian services. Peer discovery, replacement, reconnection, and transfer remain unit, CLI, and Compose E2E responsibilities. |
|
| ID generation performance | Automatic, individual | Read-only | Measures legacy and independent IDs using fixed in-memory inputs, including key derivation and heap samples where available. Keep Obsidian in the foreground. |
|
||||||
|
| File content hash performance | Manual | Read-only | Compares SHA-256 and xxHash64 on fixed in-memory Blob inputs. Input creation is excluded from hash timings; engine initialisation and warm-up are reported separately. |
|
||||||
| Vault fixture round trip | Automatic, explicit | Dedicated Vault fixtures | After explicit confirmation, creates, reads, modifies, renames, and removes one owned fixture tree. General Vault reflection remains covered by its separate real-Obsidian E2E workflow. |
|
| Vault fixture round trip | Automatic, explicit | Dedicated Vault fixtures | After explicit confirmation, creates, reads, modifies, renames, and removes one owned fixture tree. General Vault reflection remains covered by its separate real-Obsidian E2E workflow. |
|
||||||
|
|
||||||
**Automatic** runs only the two read-only local observations. **Full review** also starts the guided compatibility observation and asks before the Vault fixture scenario writes anything. A scenario can also be run individually.
|
**Automatic** runs only Settings lifecycle. **Full review** visits all listed scenarios, including the guided compatibility review and the two performance measurements, and asks before the Vault fixture scenario writes anything. Each scenario can also be run individually; a scenario's mode label does not by itself include it in the Automatic action.
|
||||||
|
|
||||||
These observations deliberately do not repeat stronger automated workflows. They exist to record which contracts the current real-device composition exposes while a maintainer reviews an immutable artefact.
|
These observations deliberately do not repeat stronger automated workflows. They exist to record which contracts the current real-device composition exposes while a maintainer reviews an immutable artefact.
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,11 @@ The current benchmark measures the Node CLI process. It does not establish Obsid
|
|||||||
|
|
||||||
## Reproducible benchmark
|
## Reproducible benchmark
|
||||||
|
|
||||||
The benchmark is implemented under `src/apps/cli/testdeno` and packaged by `test/bench-network`. It uses the real CLI mirror and synchronisation path, Commonlib 0.1.0-rc.4, CouchDB 3.5.0, the V3 Rabin–Karp splitter, optional Data Compression, and E2EE V2. It runs each of these conditions three times in rotating order:
|
The benchmark is implemented under `src/apps/cli/testdeno` and packaged by `test/bench-network`. It exercises the real CLI mirror and synchronisation path. The recorded three-repeat result below used Commonlib 0.1.0-rc.4, CouchDB 3.5.0, the V3 Rabin–Karp splitter, optional Data Compression, and E2EE V2.
|
||||||
|
|
||||||
|
The current Compose runner installs the checked-out repository's package and lockfile with `npm ci`; Self-hosted LiveSync 1.0.42 selects Commonlib 0.2.2. Running the command below measures that checkout, rather than recreating the older package environment automatically. Keep the recorded results associated with their original measurement date and dependency version.
|
||||||
|
|
||||||
|
With the repeat count shown below, it runs each of these conditions three times in rotating order:
|
||||||
|
|
||||||
- E2EE off, compression off;
|
- E2EE off, compression off;
|
||||||
- E2EE off, compression on;
|
- E2EE off, compression on;
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ These flows do not require Bash on the host. The S3 matrix tasks, environment va
|
|||||||
|
|
||||||
### `test-mirror.ts`
|
### `test-mirror.ts`
|
||||||
|
|
||||||
- Verifies six core mirror scenarios.
|
- Verifies seven core mirror scenarios, including an unrecognised revision origin.
|
||||||
- Does not require an external remote.
|
- Does not require an external remote.
|
||||||
|
|
||||||
### `test-sync-two-local-databases.ts`
|
### `test-sync-two-local-databases.ts`
|
||||||
@@ -247,11 +247,12 @@ deno task test:daemon
|
|||||||
deno task test:push-pull
|
deno task test:push-pull
|
||||||
deno task test:sync-locked-remote
|
deno task test:sync-locked-remote
|
||||||
|
|
||||||
# CouchDB-based tests
|
# CouchDB and Object Storage tests
|
||||||
deno task test:sync-two-local
|
deno task test:sync-two-local
|
||||||
deno task test:decoupled-vault
|
deno task test:decoupled-vault
|
||||||
deno task test:remote-commands
|
deno task test:remote-commands
|
||||||
deno task test:e2e-couchdb
|
deno task test:e2e-couchdb
|
||||||
|
deno task test:e2e-matrix
|
||||||
|
|
||||||
# Explicit host-direct P2P diagnostics for cross-platform investigations.
|
# Explicit host-direct P2P diagnostics for cross-platform investigations.
|
||||||
# These are not part of the default suite or release evidence.
|
# These are not part of the default suite or release evidence.
|
||||||
@@ -260,7 +261,6 @@ deno task test:p2p-peers
|
|||||||
deno task test:p2p-sync
|
deno task test:p2p-sync
|
||||||
deno task test:p2p-three-nodes
|
deno task test:p2p-three-nodes
|
||||||
deno task test:p2p-upload-download
|
deno task test:p2p-upload-download
|
||||||
deno task test:e2e-matrix
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ After the first device connects, **Try another device without resetting** keeps
|
|||||||
|
|
||||||
Serve the production build over HTTPS or from `localhost`. Downloading `check.html` alone is not supported because the page uses built module assets and origin-scoped browser storage. The generated credentials are temporary and must not replace the settings of a production Vault.
|
Serve the production build over HTTPS or from `localhost`. Downloading `check.html` alone is not supported because the page uses built module assets and origin-scoped browser storage. The generated credentials are temporary and must not replace the settings of a production Vault.
|
||||||
|
|
||||||
|
The generated Setup URI is Time-bound, and the page shows when its current fixed UTC window ends. After that time, the page hides the URI and QR code and disables the additional-device action. Start a fresh check to configure another device. A monitor for a device which already imported the settings remains available.
|
||||||
|
|
||||||
The detailed scope and result semantics are recorded in the [browser-assisted P2P connection-check ADR](../../../docs/adr/2026_07_p2p_connection_check.md).
|
The detailed scope and result semantics are recorded in the [browser-assisted P2P connection-check ADR](../../../docs/adr/2026_07_p2p_connection_check.md).
|
||||||
|
|
||||||
## Storage and lifecycle
|
## Storage and lifecycle
|
||||||
|
|||||||
Reference in new issue
Block a user