Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
69 lines
3.2 KiB
Markdown
69 lines
3.2 KiB
Markdown
# HUX client foundation integration contract
|
|
|
|
The WebUI image packages these files. Its server derives a matching
|
|
`hux.webui_context.v1` only from the authenticated, persisted WebUI session,
|
|
the bounded server `HUX_PROJECT_SOURCE`, the trusted tenant slot, and the
|
|
router-asserted HUX subject. The browser bridge remains inert unless that
|
|
context is present and the same-origin capability endpoint advertises a
|
|
complete route set. It is versioned as `hux.v1`, contains no tenant-global
|
|
browser storage, and defaults to a hidden shell.
|
|
|
|
The router negotiation endpoint is `GET /hux/v1/capabilities`. A disabled
|
|
foundation returns 404. An enabled response is:
|
|
|
|
```json
|
|
{
|
|
"schema": "hux.capabilities.v1",
|
|
"contract_version": "1.1.0",
|
|
"identity": {
|
|
"tenant_slot": "slot-3",
|
|
"subject": "usr_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
"surface": "chat",
|
|
"trust": "relay"
|
|
},
|
|
"cards": [
|
|
{
|
|
"card": "HUX-11",
|
|
"flag": "hux.foundation",
|
|
"enabled": true,
|
|
"routes": ["/hux/v1/capabilities", "/hux/v1/context/bootstrap"]
|
|
}
|
|
],
|
|
"server": {}
|
|
}
|
|
```
|
|
|
|
The boot bridge reads opaque identity and scope only from `S.session.hux_context`.
|
|
That record must bind its `webui_session_id` to the loaded WebUI session. The
|
|
bridge compares it to the authenticated BFF capability identity before it
|
|
mounts anything. It must never pass a raw Keycloak subject, email, Telegram
|
|
identifier, or tenant ordinal. The client rejects an identity or surface
|
|
mismatch, unknown versions, cross-user objects, and cross-conversation
|
|
records. It does not use local/session storage.
|
|
|
|
Opaque IDs use a server-owned 32-byte key at `HUX_CONTEXT_KEY_FILE`, or
|
|
`$HERMES_WEBUI_STATE_DIR/.hux-context-key` by default. The file is created
|
|
before context is emitted and must remain an owner-only regular file. Chat and
|
|
Worker derive the same IDs with `hux.context.id.v1`; no browser value can
|
|
select the subject, slot, key, or default project source. The project source
|
|
defaults to `profile:default` when its server environment override is absent.
|
|
|
|
After capability negotiation, the bridge sends the exact server-derived scope
|
|
to `POST /hux/v1/context/bootstrap` with CSRF and an idempotency key. The HUX
|
|
service recomputes every ID from the shared key and creates or verifies the
|
|
project/conversation binding. The drawer is not created unless that response
|
|
matches the authenticated context exactly.
|
|
|
|
Feature extensions register an id, label, HUX flag, display order, and render
|
|
callback with `HermesHuxShell.createShell()`. The shell is hidden for a 404,
|
|
for an off foundation, or when no registered extension is enabled. Loading and
|
|
errors are accessible status regions; errors disclose no backend body. Event
|
|
adapters omit `detail`, evidence URIs, hashes, and tool payloads. Object
|
|
adapters return display metadata only. Feature code must fetch sensitive
|
|
details from its owning tenant-scoped endpoint after an explicit user action.
|
|
|
|
Scripts load in dependency order and the image service worker caches the same
|
|
reviewed assets. No manifest or live HUX flag is changed by this browser
|
|
bundle. A 404, missing server context, incomplete route advertisement, or
|
|
session change destroys or suppresses the workspace.
|