Skip to content

feat: enable minimal plaintext presence in encrypted workspaces - #1999

Merged
zxch3n merged 3 commits into
mainfrom
minimal-plaintext-presence
Oct 28, 2026
Merged

zxch3n merged 3 commits into
mainfrom
minimal-plaintext-presence

Conversation

@zxch3n

@zxch3n zxch3n commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Related issue

Refs #1967. Supersedes closed, unmerged #1994.

Problem / pressure

Encrypted workspaces currently suppress presence, hiding machine liveness, session activity and viewers. The selected approach exposes minimal liveness metadata over the existing plaintext ephemeral channel. IDs, status enums and timestamps overlap information available from connections, traffic and accounts; adding a separate crypto/key/replay lifecycle brings disproportionate availability and maintenance costs here.

Summary

  • Enable the existing presence adaptor, serial SDK queue, 30-second heartbeat and 90-second TTL in encrypted workspaces, using their authorized bucket and existing token owner.
  • Apply an independent field allowlist before CLI writes to either origin store and before renderer viewing publication. Permit only machine/instance/session/user IDs, fixed kind/status/activity/phase/stage enums and timestamps. Exclude all free-text details, including existing initialization detail and future unknown text fields.
  • Validate each minimal ID field separately: session UUIDs only; internally generated instance UUIDs or a bounded legacy timestamp/base36 form; machine UUIDs or 64 lowercase hex; user UUIDs, 32 alphanumerics, or local: plus 32 lowercase hex. Reject invalid viewing routes before retention/heartbeat, clear previous viewing state, and discard invalid values without throwing. Validate CLI IDs before retaining producer keys because Loro emits delete updates even for absent keys.
  • Apply the same allowlist to CLI and renderer receive projections, including local IPC snapshots. Ignore extra fields and discard entries with invalid permitted fields independently.
  • Remove the unavailable-online-status notice through the shared capability verdict. Preserve CLI online/offline/unknown semantics: unavailable or unjoined presence remains unknown and does not alone block sending.
  • Keep ordinary presence payloads, parsing, routing and TTL unchanged. Keep other protected-workspace side channels disabled and document sync independent.
  • The presence body codec from feat: add candidate E2EE realtime body codecs #1990 is unused and is not deleted; its disposition is separate follow-up. No encrypted-presence implementation from feat: encrypt ephemeral workspace presence #1994 is carried into this branch.

Visual explanation

encrypted workspace:
  CLI machine/session or UI viewing
    -> minimal field allowlist
    -> existing Loro EphemeralStore adaptor + plaintext ephemeral POST/SSE (90s TTL)
    -> minimal receive parser
    -> liveness projection

ordinary workspace -> existing publication/parser unchanged
presence unavailable -> unknown -> dispatch permitted
protected documents -> independent protected transport

Before / after

Before After
Encrypted workspace presence is disabled. Minimal plaintext machine/session/viewing presence is enabled.
Initialization details may appear in ordinary presence. Ordinary details remain; encrypted-workspace publication and received projections exclude them.
Encrypted sessions display an unavailable-online-status notice. The supported capability removes that notice; unknown liveness stays unknown.

Test plan

Based on main 574cfb00; affected local checks only, Node 24.22.1:

  • RED → GREEN for detail leakage, receive allowlists, runtime activation and the UI capability verdict.
  • 189 tests passed: CLI presence/session leases/document-manager composition 76; two selected dispatch-policy tests (121 unselected); components transport/runtime/UI 89; shared presence/room/epoch helpers 22.
  • Real Loro encode/apply, local-origin republishing, actual SDK POST bytes and server-style apply → encodeAll bootstrap verify wire contents and late-join compatibility. Tests cover all entry kinds, extra fields, invalid enums, ordinary detail preservation, viewing clear and unknown-before-join behavior with deterministic clocks/signals.
  • Additional RED → GREEN regressions reject text, paths, oversized IDs and trailing newlines in every ID field, verify supported generated formats, and inspect real viewing/CLI set, heartbeat and delete bytes. Ordinary arbitrary-ID parsing remains compatible. Timestamp-prefixed readable session IDs are rejected on viewing startup/heartbeat, CLI set/heartbeat/clear and receive. Non-UUID historical sessions remain unpublished in minimal mode; future support requires trusted local session-record confirmation. Manager-startup fixtures stub unrelated machine-monitor/suggestion cloud attachment, retain controlled native presence, inject the meta deadline explicitly, and release in finally. The full document-manager file passes normally and with shuffled seed 20261028; the runtime recovery file also passes. Production transport behavior is unchanged.
  • CLI, components and shared type checks; changed-file Oxfmt/type-aware Oxlint; Effect lint; public/platform/native-presence boundaries; docs check and git diff check passed. Advisory warnings remain; docs reported no errors or protected topics.

No full root build/check, deployed-gateway, installed two-device or packaged-platform acceptance. No hosted CI wait. This remains draft for owner review.

@zxch3n
zxch3n marked this pull request as ready for review October 28, 2026 04:43
@zxch3n
zxch3n merged commit 9fec3a2 into main Oct 28, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant