Lace / docs

Lace-300 · Browser Addresses

Tags: browser, urc, dx, interface

Purpose

Applications need one stable lace: address syntax that does not make an HTTP host part of a document’s identity. This specification defines canonical Lace browser addresses, relative resolution, reserved address attributes, and the JavaScript address-class behavior used by address consumers and HTTP-compatible hosts.

This is an address profile over the coordinates defined by 010. It does not select a stored record, assign browser authority, or change the meaning of a bare coordinate in Interlang or Lace porcelain. A future native browser resolution design is preserved separately under docs/experimental/browser/.

A browser address names one interface coordinate

The absolute address form is:

lace://<group>//<app>//<name>[<jsonqa>]

Examples:

lace://u//jukebox//index.html
lace://u//jukebox//join.html{jukebox:abc,via:"wss:waypoint.example/interlace"}
lace://u//whatsup//index.html{community:c-123,room:general,#:thread}

After decoding, <group>, <app>, and <name> are exactly 010 Group, App, and Name values. JSONqa is defined by 310. It is address state and is not part of the coordinate or record identity.

The profile does not accept:

An application may put an exact application-record hash in app-defined JSONqa. The address still names the interface coordinate that interprets that state:

lace://u//whatsup//index.html{message:S.EXAMPLE_MESSAGE.H3}

Frontend bundles have well-known entry coordinates

A frontend bundle is an executable interface resource tree with a designated entry document. It is distinct from the application records and address state that the loaded code reads or writes.

A frontend bundle identified by <app-name> MUST publish its base entry document at:

lace://u//<app-name>//index.html

If it has an HTTP-browser-compatibility variant, that variant MUST publish its entry document at:

lace://u//<app-name>/http//index.html

u is the exact Group. <app-name> is an application-chosen valid 010 App value; the compatibility variant appends the http App segment. Supporting resources for each variant MUST use that variant’s Group and App and ordinary Name paths relative to index.html. Hosts still resolve exact Names and MUST NOT infer index.html from an incomplete coordinate.

The base and HTTP-compatible variants are distinct App scopes. Address parsing, HTTP projection, and hosts MUST NOT erase /http, translate between the scopes, or treat one entry as an alias for the other.

These are standard bundle publication and bootstrap coordinates, not a restriction on application records or links interpreted by the loaded code. A frontend MAY additionally define an application-specific interface under a different Group or App, but that does not change its well-known publication coordinates. The convention does not grant authority, select records, or make u special for non-frontend records.

Browser addresses use a custom parser

lace: is not parsed as an HTTP-style authority URL. In lace://u//jukebox//index.html, u is the Group; it is not a DNS host.

The lexical form is:

browser-address = "lace:" encoded-coordinate [jsonqa]
encoded-coordinate = "//" encoded-group "//" encoded-app "//" encoded-name

The parser MUST isolate a terminal JSONqa object before applying generic URL query or fragment processing. Raw ? and # have no query or fragment meaning in a Lace browser address. The # fragment attribute lives inside JSONqa. A canonical address uses the canonical 310 serialization of its JSONqa.

The two // field separators are found before percent-decoding. Valid 010 path values contain no empty segment, so raw // cannot occur inside Group, App, or Name.

Canonical field encoding

Each decoded field is first validated under 010 and encoded as NFC UTF-8. The canonical browser spelling leaves these ASCII bytes unescaped:

A-Z a-z 0-9 - . _ ~ /

Every other UTF-8 byte is written as %HH with uppercase hexadecimal digits. In particular, %, ?, #, quotes, spaces, and non-ASCII bytes are percent-encoded when they are coordinate field data.

A parser MUST reject:

A percent-encoded / is non-canonical and invalid. A backslash is never normalized to /. Coordinate equality compares decoded 010 values, not percent-encoding spelling.

Reserved JSONqa attributes

This profile reserves these top-level 310 attributes:

Attribute Required value Address meaning
# string application fragment or view target
via string syntactically valid 060 ILTP endpoint hint
by canonical 009 verification-key text interface by constraint

Other attributes are app-defined. Reserved attributes remain visible as address state but do not become record fields, record identity, browser authority, peer identity, exposure, or permission. Duplicate attributes first undergo 310’s last-wins reduction and are then validated.

Reusable private capabilities and By-secret values MUST NOT appear in a browser address.

via tells a consuming application or browser where it may try an acquisition. It does not establish trust in that endpoint or grant transport permission. A canonical wss: value lets a connected runtime select the default confidential peer-proof mode, but only a successful live proof derives PeerConfidential; parsing the address derives no authority. by constrains a consumer that already has an interface key configuration. It does not create or replace that configuration. A Mark is record-version-specific and is not a valid by value. The V prefix in a by value is 009’s verification-key type tag.

The address parser validates only the value shape and retains the attributes. A consuming profile owns their operational behavior.

Relative references resolve inside Name

Given:

lace://u//jukebox//pages/join.html{room:abc}

relative resolution is:

style.css       -> lace://u//jukebox//pages/style.css
./style.css     -> lace://u//jukebox//pages/style.css
../main.mjs     -> lace://u//jukebox//main.mjs
/admin.html     -> lace://u//jukebox//admin.html
//u//other//index.html -> lace://u//other//index.html
lace://u//other//index.html -> lace://u//other//index.html

The resolver first isolates a terminal JSONqa object, then interprets the raw path relative to Name. Rules:

Literal . and .. are navigation syntax only and never become stored Name segments. Generic WHATWG authority/path normalization is not authoritative for these rules.

Address classes preserve canonical state

The JavaScript surface uses classes rather than plain object snapshots:

A host profile may install one stable LaceWindowAddress as window.address. Assigning window.address forwards to its href. Host-driven updates mutate the live object and its stable urc object rather than replacing either one. Lace-320 defines this behavior for HTTP compatibility mode.

qa exposes strings, arrays, and null-prototype objects while retaining 310 object order for canonical serialization.

Two browser addresses are semantically equal when their decoded Group, App, and Name values and reduced ordered JSONqa values are equal. Canonical serialization is the stable byte key for history and address storage.

Errors

Malformed coordinates, invalid percent encoding, invalid JSONqa, malformed reserved attributes, and relative references that escape the Name root are errors. Parsing an address has no record-loading, network, trust, or navigation side effect.