Addressing and discovery
xtxp:// — the native scheme
Section titled “xtxp:// — the native scheme”xtxp://{host}/{path}@{ref}Used by native desktop clients, terminal interfaces and automated nodes exchanging XTXP streams. Whether it names the WebSocket binding directly or resolves to it through a muppet disco is still open.
https:// — served by the hosting muppet
Section titled “https:// — served by the hosting muppet”https://{host}/{path}@{ref}A muppet that hosts a session serves it to ordinary browsers itself, through its server-side muppet. This is all the MVP needs.
https://xtxp.link/ — a muppet disco
Section titled “https://xtxp.link/ — a muppet disco”https://xtxp.link/{host}/{path}@{ref}sketch · a future milestone
xtxp.link doesn’t host or serve documents. It is a muppet disco: it finds the muppets hosting the sessions behind an address, and only those the asking key may see, then hands the client on to them. Anyone can run a disco; xtxp.link is one.
One address form
Section titled “One address form”{host} can be a muppet hosting native documents, or an ordinary website. There is no separate proxy mode. A website is simply a document whose upstream peer is the origin site, and everything else about it is branching.
The @{ref} suffix says which version you mean:
| Ref | Meaning |
|---|---|
@origin |
The website’s authoritative version, as served by its origin server: the upstream peer’s session. Websites only, read-only. |
@main |
The shared collaborative session. The default for native documents. |
@{session} |
A named session on this host: a proposed edit, an undo fork, someone’s overlay. A session on another host is addressed through that host: xtxp.link/{other-host}/{path}@{session}. |
@{snapshot} |
An exact point in history: a short hash of a snapshot. Syntax open. |
Examples:
xtxp.link/en.wikipedia.org/wiki/Browser@origin Wikipedia's page, uneditedxtxp.link/en.wikipedia.org/wiki/Browser@notes an edited session of itxtxp.link/my-laptop.lan/drawing@sketch a fork, living on a laptopxtxp.link/xtxp.example.org/drawing@main a native documentxtxp.link/medium.com/@campey/post@origin "@campey" stays in the pathPrior art: the @ reads like npm’s package@version, and origin follows both git’s authoritative remote and HTTP’s origin server (prior art).
Parsing rules
Section titled “Parsing rules”- The last
@starts the ref. Every other@belongs to the path, so origin paths like Medium’s/@userneed no escaping. - Generated links always carry a ref. That includes every link it rewrites inside a page, so the last
@is never ambiguous. - Bare URLs (typed or pasted from elsewhere):
- with no
@at all, redirect to the default ref (@originfor websites,@mainfor native documents) - with an
@whose text doesn’t resolve to a ref, as inmedium.com/@campey, treat it as part of the path and redirect to…/@campey@origin
- with no
- A first path segment without a dot is a keyword, reserved for the disco’s own pages (such as
/d/for diagrams). Hostnames always contain a dot, so the two never collide.
The ref is the honesty signal
Section titled “The ref is the honesty signal”@origin means unedited. Any other ref means a session that may contain other people’s edits, and the page frame says so, with links to @origin and to the original site. The ref travels with every shared link, so a reader can tell what they’re looking at before they click. That supports the overlay safety requirements.
Content negotiation
Section titled “Content negotiation”| Request | Response |
|---|---|
| WebSocket upgrade | The live XTXP stream of Yrs updates, for muppets and automated nodes (The Wire). |
Accept: text/html |
The current state rendered as HTML, with forms that POST edits. Served by the host’s server-side muppet. |
| A person who wants their native client | A plain link to xtxp://{host}/{path}@{ref}. |
The no-JS edit loop
Section titled “The no-JS edit loop”decided for M2 (decision 23)
- At heart, every edit is a form POST. The page around it can be as rich as HTML and CSS allow.
- The forms: select an element (a link per element), edit an attribute, recolour, move (x and y fields, or nudge buttons), delete, and add a basic shape.
- Every POST carries the node ID it acts on and the snapshot hash the page was rendered from, so the host can tell when someone edited a stale page.
- Every form carries a CSRF token.
Rendering safety
Section titled “Rendering safety”What a document may contain, scripts included, isn’t the protocol’s business. Hosts serving user documents still face real risks: scripts in user SVG, and pages that run on the host’s own origin. Sanitising, a strict CSP and a separate origin for user content are the usual answers, to revisit before hosting other people’s documents in earnest.
Deep links and short links
Section titled “Deep links and short links”- Snapshots:
@{snapshot}names a document at an exact point in history, so a historical state can be shared exactly. How the snapshot hash is written in a URL is open. - Discovery: a muppet disco resolves an address to the muppet currently hosting the session.
- Short links: short, low-density URLs that make easily scanned QR codes, for bridging paper and screens.
Media types
Section titled “Media types”- Patch documents can reuse
application/xml-patch+xml(RFC 7351). - Whether the XTXP stream needs a registered media type at all, now that it travels over a WebSocket upgrade rather than HTTP content negotiation.