Tags: browser, http, compatibility, dx
Applications need to use 300 browser addresses in ordinary HTTP browsers. This specification defines an HTTP bridge, JavaScript address classes, and a fallback for ordinary HTML links.
The bridge provides address compatibility, not checked native-browser
resolution. The HTTP server chooses the executable bytes and asserts any
Group, App, or interface key metadata presented to JavaScript. The
future checked resolution design is non-normative and lives under
docs/experimental/browser/.
A compatibility host exposes a bridge base such as:
https://host.example/lace
Appending a 300 encoded coordinate gives its HTTP path:
lace://u//jukebox/http//join.html
https://host.example/lace//u//jukebox/http//join.html
Everything after /lace uses the 300 encoded-coordinate
grammar:
//<group>//<app>//<name>
The host may configure any number of (Group, App)
mappings. Each mapping names an interface key, represented by a
canonical By value, and a filesystem checkout or another
app-owned resource source. A syntactically valid coordinate always has
an HTTP projection; an unconfigured mapping returns not found.
Lace-300 requires the HTTP-compatible frontend identified by
<app-name> to publish its entry at
//u//<app-name>/http//index.html. A compatibility
host serving that bundle therefore maps Group u and App
<app-name>/http. The /http segment
remains part of App in window.address; HTTP projection does
not translate it to the base bundle’s <app-name> App
scope. Application-chosen addresses outside that publication coordinate
retain their ordinary 300 meaning.
This path shape preserves ordinary relative references. From:
https://host.example/lace//u//jukebox/http//pages/join.html
../main.mjs resolves to:
https://host.example/lace//u//jukebox/http//main.mjs
There is no separate static-resource route.
The host matches the bridge base on a segment boundary and parses the remaining raw path with the 300 custom coordinate parser. It splits structural separators before percent-decoding and decodes each field exactly once.
The host MUST reject malformed encoding, encoded /,
decoded backslash, empty segments, . or ..
traversal, and decoded values invalid under 010. A reverse proxy that
merges //, decodes separators, or normalizes the path
before the host sees it is incompatible with the bridge.
A host root outside the bridge may redirect to one configured entry address. The bridge itself serves only complete Group/App/Name paths and does not infer an entry Name from an incomplete coordinate.
Query and fragment text do not enter Name.
The HTTP projection supports top-level JSONqa strings and arrays:
# is invalid;via or by is invalid;#
attribute;#;# with the empty
string.Examples:
?page=5 -> {page:5}
?tag=a&tag=b -> {tag:[a,b]}
?draft= -> {draft}
?page=5#results -> {page:5,#:results}
?via=wss%3Ahost%2Finterlace -> {via:"wss:host/interlace"}
?by=V.EXAMPLE.H3 -> {by:V.EXAMPLE.H3}
Query parsing uses UTF-8
application/x-www-form-urlencoded decoding, including
+ as SP. Fragment parsing uses UTF-8 percent-decoding
without translating +. Malformed encoding is invalid.
Decoded keys and values MUST satisfy 310, and #,
via, and by MUST satisfy 300.
The inverse emits a scalar as one query pair, an app-defined array as
repeated pairs, and # as the fragment. Nested objects and
nested arrays are not representable. A compatibility URL generator
rejects a browser address outside this subset.
EXAMPLE By values are symbolic rather than
valid 009 payloads.
The compatibility bootstrap descriptor has this shape:
{
"profile": "lace-http-browser-compat-v1",
"group": "u",
"app": "jukebox/http",
"by": "V.EXAMPLE_INTERFACE_BY.H3",
"bridgeBase": "https://host.example/lace"
}
All fields are required for a bridge page that installs
window.address. Group and App validate under 010, and
by uses canonical 009 verification-key text. The
V prefix is 009’s verification-key type tag.
bridgeBase is an absolute HTTP or HTTPS URL with no query
or fragment. A page that only installs Lace-anchor fallback needs
bridgeBase but no current Group/App descriptor. How the
page receives configuration is an app-hosting choice.
In HTTP mode, the server and compatibility library assert this
metadata. They do not create browser authority. A projected
by value must equal the configured interface key; mismatch
fails startup.
The library supplies the URC, Address,
WindowAddress, and LaceWindowAddress classes
defined by 300.
On a bridge page, window.address is one stable
LaceWindowAddress. Reading window.address.href
returns the canonical 300 address reconstructed from the HTTP path,
query, and fragment. Assigning a valid browser URC to
window.address.href converts it to the HTTP bridge URL and
navigates with window.location. Assigning
window.address forwards to href.
App and fragment changes with unchanged via and
by update the live address without reloading. Changing
via or by performs a full HTTP navigation.
Apps use window.address.href for programmatic Lace
navigation. They do not assign window.location a
lace: URL in compatibility mode.
Any HTTP page that installs the compatibility library with a
bridgeBase may write a canonical Lace link:
<a href="lace://u//whatsup/http//index.html{room:general}">
Open room
</a>
In compatibility mode the library parses the Lace address, stores its
canonical form in data-lace-href, and replaces
href with the HTTP projection:
<a
href="https://host.example/lace//u//whatsup/http//index.html?room=general"
data-lace-href="lace://u//whatsup/http//index.html{room:general}"
>
Open room
</a>
The library processes existing anchors and anchors added or changed later. An invalid or unrepresentable Lace address fails conversion and MUST NOT fall through to external-protocol navigation.
Rewriting href preserves normal left click, middle
click, context-menu, target, and new-window behavior. HTTP
browsers copy the HTTP fallback from the rewritten href;
applications that offer a Lace-address share action use
data-lace-href or an Address value.
The compatibility library assumes that it is the active fallback and does not try to detect an operating-system protocol handler.
The reference host serves configured filesystem trees. Another app host may produce the same HTTP shape from its own resource source, but the HTTP browser cannot distinguish sources from JavaScript address state. This profile does not define a checked-record resolver. The server can replace the bytes or compatibility code, so HTTP remains the execution authority.
An HTTP origin may host several Lace (Group, App)
address scopes. The HTTP browser treats them as same-origin and
collapses their DOM, storage, worker, cookie, and window isolation. This
is a known bridge limitation, not an invalid deployment.
The host should support GET and HEAD and return a non-success status for an unknown or invalid coordinate. HEAD returns the GET metadata without a body.
Active resources need a correct Content-Type and
X-Content-Type-Options: nosniff. The host preserves
relative document, module, stylesheet, worker, image, and media paths.
It does not turn an unknown Name into a command or unrelated entry
page.
Normal HTTP cache, CSP, referrer, TLS, proxy, authentication, and access-control policy remains deployment policy.
via remains a Lace
hintAn HTTP query via projects the 300 acquisition hint. The
app may use it with browser Lace operations. It does not make the HTTP
server or endpoint an interface authority, prove peer identity, or grant
app authority. A consuming runtime may use canonical wss:
for the 060 confidential-channel default, but
PeerConfidential still requires the live minimal Seal
proof. A reverse proxy terminating WSS and forwarding WS to
laced requires the explicit backend
trust-confidential-channel override; that complete proxy
path becomes trusted.
An app-specific default endpoint stays outside address state unless
the host redirects to an HTTP URL containing via.
laced is not
the compatibility hostThe compatibility host is app or reference infrastructure. A
laced ILTP listener MUST NOT serve these application
routes.
A reverse proxy may expose the app host and a laced
WebSocket listener under one public host, but /lace and
/interlace remain separate roles.
The bridge rejects malformed bootstrap values, coordinates, path
encoding, query or fragment state, JSONqa, and by
mismatches. It returns an error for an unconfigured Group/App or missing
interface resource.