CultLib/packages/cultmesh-browser
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Meta Vens dfe582edbc Kill the browser's local reading of "unsigned", and mutate the browser too
Soul replaced the shared `isUnsignedCertificate` call in the browser's
session-acceptance check with a local empty-string comparison and every one of
the 18 browser tests still passed, because every test used an empty signature.
A whitespace signature is where the two readings part: the shared route
verifier accepts such a route as unsigned on a loopback local-development
endpoint, and an inline comparison then demands a provider proof for the
session the verifier just let through. The test now opens that session with
three spaces, U+0085 and a no-break-space/tab/newline mix as well as the empty
string, and asserts U+FEFF the other way, since it is whitespace to JavaScript
and a signature to C#.

The mutation runner grew a second target. `shared` is the one verifier, killed
by the cultnet-ts tests; `browser` is `packages/cultmesh-browser/src/index.ts`,
killed by the browser tests. A browser mutation cannot be killed by cultnet-ts
tests, so the killer is the target's own workspace, and each target carries its
own sidecar, control, sentinel and post-restore dist assertion.

Two repairs this pass earned:

- The sidecar is now removed inside the `finally`, right after the verified
  restore. A throw mid-run left it behind holding the pre-run bytes, and the
  next run "repaired" the file from them, silently reverting everything fixed
  in between. That happened here, twice, before it was noticed.
- The NUL in the loopback pre-check's strip regex had been written as a literal
  byte rather than an escape. It read the same, but git classified the file as
  binary and stopped normalising its line endings, so the whole file diffed as
  rewritten. Escaped, along with the ASCII host range beside it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 17:39:50 +02:00
..
src Share one reading of an unsigned certificate between verifier and browser 2026-09-16 16:43:09 +02:00
test Kill the browser's local reading of "unsigned", and mutate the browser too 2026-09-16 17:39:50 +02:00
package.json Bind CultMesh authority identity to physical routes 2026-08-18 17:21:58 +02:00
README.md Bind CultMesh authority identity to physical routes 2026-08-18 17:21:58 +02:00
tsconfig.json Add real browser CultMesh transport proof 2026-08-18 00:05:57 +02:00
tsconfig.test.json Add real browser CultMesh transport proof 2026-08-18 00:05:57 +02:00

CultMesh Browser

cultmesh-browser is the browser-safe CultMesh client boundary. It owns one WebSocket session for a stable Verse/authority-runtime target, retains explicit raw document leases across route replacement, and correlates typed CultNet operations with provider receipts.

It does not own application state and it does not expose direct document writes. A renderer watches provider-owned records and invokes provider-owned operations.

const odin = new CultMeshBrowserOdinRendezvous({
  endpoints: ["wss://odin.example/verse"],
  runtimeId: "counter-browser.discovery",
});

const mesh = await CultMeshBrowserClient.connect({
  verseId: "sample.counter",
  authorityRuntimeId: "sample.counter-daemon",
  runtimeId: "counter-browser",
  rendezvous: odin,
});

const counter = await mesh.leaseRawDocument({
  schemaId: "sample.counter_state.v1",
  recordKey: "counter:main",
});

counter.watch(record => renderCounter(decodeCultNetPayload(record)));

invoke(...) returns the correlated provider response. Routing, schema, and envelope failures reject immediately with CultMeshBrowserOperationError; callers can branch on its stable status and code without parsing prose or waiting for the request timeout. Domain rejections remain typed provider responses because the domain still owns their receipt schema.

CultMeshBrowserOdinRendezvous speaks the canonical CultNet Verse-catalog messages to one or more configured Odin WebSocket endpoints. Application code supplies the Verse and authority-runtime identity; it does not own endpoint selection, reconnect, or resubscription. This is deliberately distinct from an Eve surface's providerId, which identifies the UI provider inside the Verse. The physical socket is a replaceable route, not either stable identity.

Odin returns exact authority-route bindings. The browser selects only routes bound to the requested authority and cultmesh.documents.v1, then performs a session-open handshake. It does not report connected until the peer proves the exact Verse, authority runtime, protocol, and route generation. Operation responses must also name that authority. Legacy catalogs are accepted only when one authority runtime makes the endpoint binding unambiguous.

The browser handshake carries authentication through the host application's ordinary secure cookie or equivalent upgrade credential. The C# host adapter rejects endpoints without an authorization predicate unless anonymous local development is explicitly enabled.

Run scripts/verify-eve-browser-network.mjs --eve-root <path-to-Eve> for the real Chromium + C# headless chronology. The witness publishes a lower-priority decoy endpoint owned by another runtime and proves that neither client connects to it before and after route rotation.