UI Addressing
Purpose
This document fixes the target addressing model for AdaOS browser-facing UI, runtime manifests, projections, and domain-facing operator surfaces.
The goal is not to replace every existing path or identifier with one universal string format. The goal is to define one coherent vocabulary so that:
- skills and scenarios can be authored by humans and LLMs without guessing
- browser-facing manifests can bind data and actions safely
- runtime services can preserve scope and ownership across Yjs, streams, and projections
- domain-specific surfaces such as device access can reuse the same model
This is a target-state architecture document. Current implementation details remain documented in:
- the repository note
docs/io/webio.md - Operational Event Model
- Webspace Evolution Roadmap
- Device Access and Browsers
- Named Entities and Canonical Naming
Governing Rules
- Do not expose raw storage topology as the primary authoring contract.
- Keep logical authoring addresses separate from runtime materialization refs.
- Keep domain identity refs separate from state refs and action refs.
- Keep scope explicit whenever state may be shared, node-owned, or local.
- When skill-owned browser state must stay shared, declare ownership explicitly in the skill manifest rather than relying on client-side exceptions.
- Prefer deterministic, typed refs over ad hoc string conventions.
- LLM-oriented authoring should use a compact, repetitive vocabulary.
Non-Goals
This document does not require:
- one URI syntax for every internal AdaOS concept
- immediate replacement of existing
ctx.*,data_projections, orwebio.stream.*contracts - direct skill authoring against Yjs paths
- a hard mandate that every ref becomes browser-visible
Addressing Layers
AdaOS now needs one model with several layers, not one flat namespace.
1. Logical authoring layer
This is the layer skills and scenarios should reason about first.
Examples:
ctx.user.profilectx.state.review.selection- logical projection slots declared through
data_projections
This layer is stable for authoring and should remain storage-agnostic.
2. Projection-routing layer
This is the layer that maps logical state to runtime backends.
Examples:
(scope, slot)pairs indata_projections- scenario- or skill-owned mapping into Yjs, KV, SQL, or future backends
This layer is authoritative for data placement decisions.
3. Runtime UI binding layer
This is the layer browser-facing manifests and runtime adapters bind to.
Examples:
- Yjs-backed state refs
- browser stream receiver refs
- local view-state refs
- action refs
- projection refs
This layer is where semantic UI manifests should live.
4. Domain identity layer
This layer identifies real entities and reusable domain objects.
Examples:
device:browser:<device_id>device:member:<node_id>webspace:<webspace_id>
Human-facing names and aliases for these refs are governed by the named-entity layer described in Named Entities and Canonical Naming. The domain ref stays stable when a label changes.
This layer is shared across UI, SDK, runtime, and operator tooling.
Canonical Ref Classes
The target model uses a small typed vocabulary.
Logical refs
Logical refs are authoring-level and storage-agnostic.
Examples:
ctx.user.profilectx.ui.web.desktopctx.voice.morning.current_step
Runtime state refs
Runtime state refs bind browser-visible state to a concrete runtime-backed state family.
Examples:
y:data/reviews/currenty:data/nodes/member-01/infrastate/summaryy:ui/application
Stream refs
Stream refs identify transport-independent live browser receiver families.
Examples:
stream:chat.livestream:infrastate.operations.active
Stream refs identify the semantic receiver family. Webspace targeting, node ownership, and transport preference remain binding properties rather than part of the ref identity itself.
View-state refs
View-state refs identify client-owned interaction state.
Examples:
view:filters.statusview:columns.enabledview:review.selection
Projection refs
Projection refs identify demanded materialized UI views.
Examples:
projection:overviewprojection:inventory:membersprojection:modal:workspace-manager
projection_key remains the canonical key within projection payloads.
This document treats projection:<projection_key> as the addressing form used
when projection identity must participate in a broader ref vocabulary.
Action refs
Action refs identify typed browser-visible or runtime-visible operations.
Examples:
action:skill.chat.sendaction:device_access.renameaction:webspace.open
For current compatibility work, one action ref may still resolve through
existing callSkill, callHost, or modal-opening behavior.
The important boundary is to keep the browser-facing action identity stable
even while the underlying compatibility bridge evolves.
Domain refs
Domain refs identify reusable domain entities rather than UI state.
Examples:
device:browser:abc123device:member:member-01webspace:desktop
Human names are not refs
Human-facing names such as Kitchen display, ZVERZVE-A1BNQF7, Edge on
Windows, or Node 0 are labels, not addressing refs.
They may resolve to a domain ref through the named-entity layer.
Localized labels and aliases follow the same rule: the active language can
change which text is displayed or matched, but it must not change the target
domain ref.
Addressing contracts should not encode these labels as routing keys.
Correct shape:
{
"target": {
"ref": "device:member:8db40740-b3ff-44bf-baf5-9fb013b35b01",
"label": "ZVERZVE-A1BNQF7"
}
}
Avoid:
The label is display-only and may change without invalidating the ref.
Scope Model
Addressing is not complete without scope.
The target scope vocabulary is:
shared: collaborative state shared within one webspacenode: state owned by one node inside a shared webspacelocal: browser-local state not synchronized through shared runtime stateworkspace: durable or logical scenario/workspace scope outside a browser local session
The preferred semantic binding shape is an object, not only a string:
This avoids encoding too much meaning into one ad hoc path string.
Canonical vs Derived State
The model must distinguish canonical truth from browser-facing derived state.
Canonical examples
- logical state behind
ctx.* - durable workspace metadata
- shipped scenario content
- shipped skill
webui.json - access-link policy records
Derived examples
ui.application- demanded projection payloads
- grouped or filtered client view state
- browser stream buffers
Yjs may contain both live collaborative truth and derived materialization, but the addressing model must not blur those ownership boundaries.
Relationship to Existing Contracts
ctx.*
ctx.* remains the primary logical authoring contract for skills and
scenarios.
It is not replaced by browser-visible Yjs or stream refs.
data_projections
data_projections remain the canonical routing layer between logical state and
physical backend placement.
This document does not replace (scope, slot) pairs.
It makes clear how browser-facing refs relate to that routing layer.
webio.receivers
webio.receivers remain the canonical declaration mechanism for
transport-independent browser stream families.
This document treats each receiver family as a stream:<receiver> ref at the
addressing level.
projection_key
projection_key remains the canonical deterministic identity for demanded
materialized UI views.
This document only gives it a consistent typed-ref role in the wider
vocabulary.
DeviceRef
Device-facing refs such as browser:<device_id> and member:<node_id> should
evolve toward an explicitly typed domain-ref vocabulary:
device:browser:<device_id>device:member:<node_id>hub:<subnet_id>for the local hub settings target
Device-facing architecture may continue to document the shorter
browser:<device_id> and member:<node_id> forms during migration, but the
target vocabulary should be explicit about the domain class.
If a local hub is observed through the legacy member:<local_node_id> form,
the device-access layer must normalize it to hub:<subnet_id> before exposing
settings or command availability.
Use subnet endpoint for the software participant attached to the subnet.
browser and member are endpoint kinds; device and client are
operator-facing access classes.
The naming layer should resolve user-facing labels and aliases into these refs before actions are dispatched. UI manifests should bind to refs, not to mutable display strings.
Named Entities
Named entities are the bridge from human language to addressing.
The boundary is:
- UI Addressing defines stable typed refs and binding shapes.
- Named Entities define display names, observed names, aliases, ambiguity, and locale-aware text-to-ref resolution.
- NLU and operator tooling should resolve labels to refs before dispatching
action:*commands. - Manifests may include display labels for readability, but action payloads, projection demand, and state binding should use typed refs.
Examples:
"show logs for kitchen display"resolveskitchen displaytodevice:member:<node_id>, then dispatches an action with that ref.- A device settings form displays
ZVERZVE-A1BNQF7, but the save action targetsdevice:member:<node_id>. - A browser settings modal may show
Edge on Windows, but modal addressing should still use the modal/action ref plusdevice:browser:<device_id>. - A Russian alias such as
рабочий браузерand an English alias such aswork browsermay resolve to the samedevice:browser:<device_id>; neither alias becomes an addressing key.
The direction must stay one-way:
- user phrase or UI label
- named-entity resolution
- typed domain ref
- action, projection, or state binding
Typed refs should never be derived by parsing display strings.
Priority Slice for Web UI
The first addressing slice needed by the browser runtime is intentionally small.
Required first
- Yjs state refs
- stream refs
- local view-state refs
- typed action refs
- projection refs
webspace:<id>anddevice:*domain refs where browser surfaces need them
Deferred
- broad generalized URI layers for non-UI backends
- a universal cross-plane query language
- automatic ref rewriting across all historical contracts
- per-user projection payload forks
Recommended Binding Shape for Semantic UI
Semantic UI manifests should bind through typed objects rather than opaque renderer-specific strings.
Example:
{
"source": {
"kind": "stream",
"ref": "stream:chat.live",
"scope": "shared"
},
"viewState": {
"ref": "view:chat.input"
},
"actions": [
{
"ref": "action:skill.chat.send",
"trigger": "submit"
}
]
}
For chart-like views, a compatible semantic binding should follow the same shape and only vary by semantic kind and source contract, not by introducing a second addressing model for time-series data.
LLM Authoring Guidance
For the current skill-level implementation checklist, use LLM-Safe Skill Development Guide.
LLM-authored skills and scenarios should follow these rules:
- prefer declared logical paths and typed refs over inventing new branches
- do not write directly to arbitrary Yjs paths unless the runtime contract explicitly exposes them
- keep business truth out of
view:* - keep renderer decisions out of addressing
- keep node ownership explicit instead of implied
- prefer one of the documented ref classes before introducing a new one
Roadmap
Status note:
- the typed ref vocabulary is now documented and used by the draft semantic Web UI ABI
- demo skill and scenario manifests already use
y:,stream:,view:, andaction:refs - desktop and modal runtime adapters now preserve the same binding vocabulary during compatibility rendering
- the first Taiga-backed
collection_gridrenderer consumes the samey:andview:refs without introducing renderer-specific addressing - the Taiga-backed
metric_chartrenderer consumes the samey:andview:refs without introducing chart-specific addressing - the semantic
chat_panelnow consumes the same typedy:bindings without introducing a separate chat-only addressing model - the widget host now resolves Taiga-backed semantic renderers through lazy registry entries, while keeping the same typed binding refs on the manifest side
- the demo slice now uses
action:-backedopen_modal,call_host, andinvoke_skill_actionflows against the same sharedview:andstream:refs - broader cross-document harmonization is still in progress
- the demo metrics table and chart now share the same
view:selection ref on both semantic and compatibility paths - desktop and modal runtime adapters now preserve the same node-scoped
y:binding behavior for the demo slice - the demo package now reuses the same typed refs across both
workspaceandoperationssurface classes - semantic workspace metadata is now mirrored into
runtime.surface.*browser state so typed actions can carry stable surface context without inventing a second addressing model - typed
open_workspaceactions can now target a first-class shell route (workspace) in addition to modal and webspace-switch flows
0. Vocabulary Fixation
- [x] publish this addressing vocabulary as the canonical browser/runtime reference model
- [x] freeze the distinction between logical, routing, runtime, projection, action, and domain refs
- [ ] align naming guidance across
ctx.*,data_projections,webio.receivers, andprojection_key
1. Cross-Document Harmonization
- [ ] update scenario and skill architecture docs so
ctx.*is explicitly the logical authoring layer - [ ] update projection docs so
projection_keyis explicitly the projection ref identity - [ ] update device-access docs so
DeviceRefis documented as a domain-ref slice - [ ] keep named-entity docs aligned so human-facing labels resolve into domain refs but never become addressing refs themselves
- [ ] keep localization guidance aligned so localized labels affect display and resolution priority, not addressing identity
- [ ] update browser/runtime docs so Yjs, streams, and local view state are described through the same scope vocabulary
2. Web UI Priority Slice
- [x] define the first browser-facing binding object shape for
y,stream, andviewrefs - [x] define typed browser action refs for the first semantic UI actions
- [ ] define the first canonical
webspace:<id>anddevice:*refs needed by workspace and device surfaces - [ ] define the first projection-ref usage rules for pages, widgets, modals, and platform-emitted projections
- [x] define the first shared binding pattern that both table-like and chart-like semantic views can reuse
3. Runtime and ABI Alignment
- [x] teach runtime manifest and semantic UI ABI docs to use the same ref vocabulary
- [x] align browser adapters with explicit scope handling instead of implicit path conventions alone
- [x] preserve compatibility for current
webui.json, Yjs, and stream contracts during migration
4. Authoring and Tooling
- [ ] publish LLM-oriented authoring examples using the finalized ref classes
- [ ] validate manifests against allowed ref kinds and scope combinations
- [ ] validate that action targets, projection demand, and state bindings do not use mutable display labels as routing keys
- [x] add repository examples covering shared, node-scoped, and local browser state
4a. Stand-Oriented Demo Readiness
- [x] repository demo manifests use
y:,stream:,view:, andaction:refs together - [x] one shared
view:ref links table selection to chart rendering - [x] the same addressing slice is used in both desktop and modal demo surfaces
- [x] desktop and modal runtime adapters scope node-owned
y:refs consistently for the same demo bindings - [x] repository demo manifests reuse the same typed refs across both
workspaceandoperationssurface classes - [x] typed host and skill action envelopes now inherit
runtime.surface.*context from semantic workspace metadata - [x] typed
open_workspaceactions can target an explicit browser workspace shell surface - [ ] manual verification on the target stand
5. Deferred Generalization
- [ ] decide whether a generalized non-UI data URI layer is still needed after browser/runtime addressing stabilizes
- [ ] if kept, position that layer as a facade over the canonical addressing model rather than as a competing architecture