Skip to content

docs(specs): define the normative popup transport - #22

Open
Wondertan wants to merge 36 commits into
mainfrom
docs/popup-connection-architecture
Open

Wondertan wants to merge 36 commits into
mainfrom
docs/popup-connection-architecture

Conversation

@Wondertan

@Wondertan Wondertan commented Sep 2, 2026

Copy link
Copy Markdown
Member

Summary

  • define the normative popup transport: endpoint admission, message model, delivery guarantees, navigation and closure, continuity across popup-document replacement, and failure semantics, as a chapter of the protocol specification
  • browser protocols cite it instead of restating opener, isolation, and continuity mechanics
  • require authenticated peer-origin access and preserve exact origin admission across restored and replacement carriers

Rendered entry points:

Motivation

The popup transport's normative rules were interleaved with implementation detail: carrier wire formats, the port keeper, timeouts, API declarations, and diagnostics. Decoupling them keeps each side tidy, but the main reason is layering. Protocol specifications built on top of the popup transport, starting with the ceremony browser contract, need a stable normative description to reference by requirement ID rather than restating browser mechanics or depending on how one package implements them.

Scope

Normative transport only. The @libid/popup package documentation (API, MessagePort and WebRTC carriers, port keeper, test plan, metrics) travels with the implementation in #25. Carrier wire formats are not an interoperability boundary today and stay with the implementation.

@Wondertan Wondertan changed the title Document popup connection architecture docs(popup): define connection architecture Sep 2, 2026
@Wondertan
Wondertan force-pushed the docs/popup-connection-architecture branch 2 times, most recently from f765914 to d3b4781 Compare September 2, 2026 19:19
@Wondertan
Wondertan requested a review from xgreenx September 2, 2026 19:27
@Wondertan Wondertan self-assigned this Sep 2, 2026
@Wondertan
Wondertan requested a review from SupremaLex September 2, 2026 19:28
Wondertan added a commit that referenced this pull request Sep 3, 2026
The @libid/popup package documentation as reviewed in #22: README,
connection, control, MessagePort and WebRTC carriers, test plan, and
metrics. The normative transport contract lives in specs/.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
@Wondertan
Wondertan removed the request for review from SupremaLex September 3, 2026 15:52
@Wondertan Wondertan changed the title docs(popup): define connection architecture docs(specs): define the normative popup transport Sep 3, 2026
Assisted-by: GPT-5
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: GPT-5
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: GPT-5
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: GPT-5
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: GPT-5
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Normative changes from the pre-implementation review:

- PortKeeper drops the unused `purpose`; expiry deletes the entry and a
  later claim yields `null` rather than a distinct post-terminal failure.
- The Service Worker is host-registered. The package exports
  `installPortKeeper(scope)` for the host's popup-origin worker script and
  `accept` claims from the registration controlling the current document
  as its first step, so the claim deadline includes document load and
  package import.
- `PopupWindow` exposes only `opened` and its factories; direct navigation
  and closure are package-internal and reachable through `PopupConnection`.
- The application MessagePort side is one connection-lifetime listener
  (`listenForPopupPorts`) yielding a port per accepted handshake, with a
  `PortCarrier` that can `detach` its port for preservation.
- `send` and `on` throw synchronously; `send` without an active carrier
  throws and queues nothing; handlers are registered synchronously after
  the connection is obtained.
- Opener handshake deadline is `OPENER_HANDSHAKE_TIMEOUT_MS = 30_000`; a
  null or closed opener counts as absent.
- After a connected navigation to a non-participating document the
  application cannot observe port expiry; it retains the carrier until
  replaced or closed, and a `navigate` issued meanwhile is lost.
- Diagnostics use a closed `PopupDiagnosticCode` union; latency and byte
  measurements are dropped because MessagePort adds no clock or encoding.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
…ndary, diagnostics

- The application window listener lives for the connection; an accepted
  handshake discards only its attempt state. Only the popup removes its
  listener after acceptance.
- Before native-anchor binding the connection ID selects attempts, so a
  valid handshake for another connection is ignored, not rejected;
  concurrent connections on one page cannot fail each other.
- `installPortKeeper` moves to the `@libid/popup/worker` subpath so
  worker-global types never enter the main declaration. "Host" is
  defined as the deployment serving the popup documents.
- `PopupDiagnostic.code` stays `string`; the catalog is open per carrier
  and a closed union would break exhaustive consumers on each addition.
- While the popup is non-participating after a connected navigation, every
  `send` and `navigate` succeeds locally and delivers nothing; stated in
  the boundary and POPUP-CONNECTION-006.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Completes 310bb06, which landed only the README and message-port.md half
of the same review:

- `installPortKeeper` is declared under the `@libid/popup/worker` subpath
  in connection.md; "host" is defined there too.
- `PopupDiagnostic.code` is `string` everywhere; METRICS.md explains why
  the catalog stays open.
- The non-participating window loses every `send`, not only `navigate`;
  stated in connection.md and POPUP-CONNECTION-006.
- POPUP-API-004 requires ignoring, not rejecting, another connection's
  valid pre-binding handshake.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
…gistration wording

- An event is a handshake attempt only with the `message-port` discriminator
  and this connection's ID, before and after binding; unrelated traffic from
  the bound WindowProxy on a provider page is ignored.
- `installPortKeeper()` takes no argument; worker `self` is typed as
  `WorkerGlobalScope`, so scope injection stays internal.
- The popup uses the active registration whose scope matches its URL; control
  of the document is not required to message that worker.
- POPUP-PORT-001 covers sequential handshakes over the lifetime listener.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Extract the protocol-facing contract of the popup connection from the
@libid/popup implementation documents into a normative chapter: endpoint
identity and admission, the message model, delivery guarantees, lifecycle
and control, continuity across popup-document replacement, and failure
semantics, with assumptions, security properties, conformance vectors,
and a provenance table back to the implementation sections. Carrier wire
formats, the keeper, WebRTC, diagnostics, and the API stay with the
implementation, which is not an interoperability boundary today.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
The normative popup transport chapter stays here; the @libid/popup
package documentation (README, connection, control, MessagePort and
WebRTC carriers, test plan, metrics) travels with the implementation.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
@Wondertan
Wondertan force-pushed the docs/popup-connection-architecture branch from 8a14db9 to f6a3c85 Compare September 3, 2026 16:15
Wondertan added a commit that referenced this pull request Sep 3, 2026
The @libid/popup package documentation as reviewed in #22: README,
connection, control, MessagePort and WebRTC carriers, test plan, and
metrics. The normative transport contract lives in specs/.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Navigation away (REQ-POPUP-CONTROL-04A) navigates the retained handle
directly for a non-participating destination, retires the carrier
without continuity, and keeps the application endpoint ready for the
next participating document. A Popup Endpoint may use the wildcard
allowlist, binding any HTTPS opener origin exactly; the Application
Endpoint's allowlist stays explicit.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Wondertan added a commit that referenced this pull request Sep 3, 2026
The @libid/popup package documentation as reviewed in #22: README,
connection, control, MessagePort and WebRTC carriers, test plan, and
metrics. The normative transport contract lives in specs/.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
- Attempts from another window or an unlisted origin are ignored, never
  fatal; only a malformed record from the expected peer fails a
  connection.
- Handler exceptions belong to the Carried Protocol and change no state.
- Both constructors return synchronously; handlers registered before
  yielding precede delivery.
- Every endpoint exposes a terminal outcome settled once, closed or
  failed with the stable code.
- Continuity is bounded by time, not by what showed in between; a silent
  continuity owner holds nothing; navigation away retires the carrier and
  keeps its destination private to the endpoint that performs it.
- Provenance IDs corrected.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Wondertan added a commit that referenced this pull request Sep 3, 2026
The @libid/popup package documentation as reviewed in #22: README,
connection, control, MessagePort and WebRTC carriers, test plan, and
metrics. The normative transport contract lives in specs/.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Protocol Messages sent before a Control are delivered before the Popup
acts on it, so a transition that carries a reply is driven by the side
that has finished talking; the transport buffers and retransmits nothing.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
…ontrol

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Wondertan added a commit that referenced this pull request Sep 3, 2026
The @libid/popup package documentation as reviewed in #22: README,
connection, control, MessagePort and WebRTC carriers, test plan, and
metrics. The normative transport contract lives in specs/.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
A Popup Endpoint may require cross-origin isolation; where the engine
does not isolate the document directly, the transport preserves the
carrier and reaches isolation through a named same-origin replacement,
invisibly to the Carried Protocol.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Wondertan added a commit that referenced this pull request Sep 5, 2026
The @libid/popup package documentation as reviewed in #22: README,
connection, control, MessagePort and WebRTC carriers, test plan, and
metrics. The normative transport contract lives in specs/.

Assisted-by: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_012SVAaP3Z7Haz18WJBjCZAw
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Define best-effort logical continuity, carrier preservation versus replacement, and the silent message-loss window. Cover fallback-only isolation, carrier authentication, private fragment preservation, and exact-loopback HTTP.

Assisted-by: GPT-5
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
Expose the origin bound to the selected carrier and require destination admission
for preserved, replacement, and fallback carriers before delivery.

Assisted-by: GPT-6
Signed-off-by: Wondertan <hlibwondertan@gmail.com>
@Wondertan
Wondertan force-pushed the docs/popup-connection-architecture branch from c690d73 to 2db150c Compare September 13, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant