UIAP Agent Cognition
UIAP Agent Cognition v0.1
Section titled “UIAP Agent Cognition v0.1”| Field | Value |
|---|---|
| Status | Draft |
| Version | 0.1 |
| Date | 2026-03-29 |
| Dependencies | UIAP Core |
| Editors | Patrick |
1. Purpose and Scope
Section titled “1. Purpose and Scope”This specification extends UIAP with a read-only Cognition Layer for agents.
UIAP Agent Cognition v0.1 defines:
- a global Entity Schema as data model
- a Scope Context for currently visible or explicitly exposed records
- a Navigation Map for spatial orientation within the app
- an optional, limited Scope Query mechanism
- a standardized Entity Reference that MAY be reused by Action/Runtime specifications
UIAP Agent Cognition v0.1 does not define:
- mutations on data
- direct database or backend access
- free, unbound ad-hoc queries
- relational joins across multiple entity types
- detailed Action execution semantics
Mutations remain the responsibility of UI Actions or other specifications defined for that purpose. This extension provides only additional, controlled context.
2. Normative Terms
Section titled “2. Normative Terms”The key words MUST, MUST NOT, SHOULD, MAY in this document are to be interpreted as described in RFC 2119 and BCP 14, when and only when they appear in ALL CAPS.
3. Design Principles
Section titled “3. Design Principles”- Read-only by design. Agent Cognition provides context, not mutation.
- Schema global, records restrictive. The Entity Schema MAY be known session-wide; concrete records SHOULD by default only be delivered within the current scope.
- Secure default. If nothing else is declared,
recordAccess = "visible_only"applies to records. - UI-bound. Agent Cognition supplements UI understanding; it does not replace an app API.
- App-controlled. The app decides which schemas, fields, counts, and records are available.
- Progressive Enhancement. Schema, Navigation, Context, and Query MAY be provided independently of each other.
- No hidden full API. Scope Queries MUST remain limited, read-only, and bound to a scope or route.
4. Core Concepts
Section titled “4. Core Concepts”4.1 Entity Schema
Section titled “4.1 Entity Schema”The Entity Schema describes which business objects the app knows and which fields those objects have.
Examples:
contactdealmemberactivity
The schema describes structure, not necessarily visible values.
4.2 Scope Context
Section titled “4.2 Scope Context”The Scope Context describes which entities are relevant in the current scope. A scope MAY be, for example:
- a route such as
/contacts - a list such as
contacts-list - an embedded region such as
dashboard-deals
The Scope Context contains by default only records that are visible in the current scope or explicitly exposed.
4.3 Navigation Map
Section titled “4.3 Navigation Map”The Navigation Map describes where in the app which entity types typically live and how an agent can navigate there.
It is an orientation aid, not a mutation.
4.4 Scope Query
Section titled “4.4 Scope Query”A Scope Query is an optional, limited mechanism for reading additional records within a declared scope or route.
A Scope Query is:
- read-only
- limited
- policy-controlled
- scope- or route-bound
A Scope Query is NOT:
- a general database access
- a free query language
- a join engine
5. Data Types
Section titled “5. Data Types”5.1 Primitive Types
Section titled “5.1 Primitive Types”type EntityType = string; // z. B. "contact" oder "deal"type EntityId = string; // app-definiert, innerhalb des EntityType eindeutigtype FieldName = string; // z. B. "name", "company", "status"type ScopeId = string; // z. B. "contacts-list"type RouteId = string; // z. B. "contacts"type Revision = string; // app-definiert für Change Detection5.2 Enumerations
Section titled “5.2 Enumerations”type CognitionSurface = "schema" | "navigation" | "context";
type RecordAccessMode = | "visible_only" // nur aktuell sichtbare Datensätze | "scope_window" // aktueller logischer Listenbereich / Fenster | "queryable"; // begrenzte read-only Queries erlaubt
type FieldType = | "string" | "number" | "boolean" | "date" | "datetime" | "enum" | "currency" | "email" | "phone" | "url" | "json";
type FieldExposure = | "readable" // Werte DÜRFEN geliefert werden | "redacted" // Werte KÖNNEN maskiert oder ausgelassen werden | "declared_only"; // Feld ist Teil des Schemas, Werte DÜRFEN nicht geliefert werden
type RecordSource = | "visible" | "scope_window" | "query";
type FilterOp = | "eq" | "neq" | "in" | "contains" | "starts_with" | "gt" | "gte" | "lt" | "lte" | "exists";5.3 Entity Reference
Section titled “5.3 Entity Reference”interface EntityRef { type: EntityType; id: EntityId; stableId?: string; // optionaler UI-Bezug, falls vorhanden primaryText?: string; // z. B. "Elena Rossi"}5.4 Entity Schema
Section titled “5.4 Entity Schema”interface EntityFieldSchema { type: FieldType; label?: string; description?: string; enumValues?: string[]; exposure?: FieldExposure; // Default: "readable" searchable?: boolean; sortable?: boolean;}
interface EntityRelation { field: FieldName; // z. B. "contactId" targetEntity: EntityType; // z. B. "contact" kind: "belongs_to" | "has_one" | "has_many" | string;}relations are in v0.1 primarily semantic declarations. They describe that a field references another entity but do not define their own traversal language.
interface EntitySchema { label?: string; primaryField?: FieldName; recordAccess?: RecordAccessMode; // Default: "visible_only" fields: Record<FieldName, EntityFieldSchema>; relations?: EntityRelation[]; actions?: string[]; // semantische oder konkrete Action-IDs}
interface EntitySchemaDocument { revision?: Revision; entities: Record<EntityType, EntitySchema>;}5.5 Record Representation
Section titled “5.5 Record Representation”interface EntityRecord { ref: EntityRef; fields: Record<FieldName, unknown>; redactions?: Record<FieldName, "masked" | "withheld" | "omitted">; source: RecordSource; actions?: string[];}5.6 Scope Context
Section titled “5.6 Scope Context”interface SortSpec { field: FieldName; direction?: "asc" | "desc"; // Default: "asc"}
interface FilterSpec { field: FieldName; op: FilterOp; value?: string | number | boolean | Array<string | number | boolean>;}
interface ScopeCollection { entity: EntityType; access: RecordAccessMode; visibleCount: number; // Anzahl aktuell sichtbarer Datensätze im Scope totalCount?: number; // optional; nur wenn die App dies freigibt offset?: number; // bei virtuellen Listen/Fenstern limit?: number; // bei virtuellen Listen/Fenstern hasMore?: boolean; filters?: FilterSpec[]; sort?: SortSpec[]; items: EntityRecord[];}
interface ScopeContext { revision?: Revision; scopeId: ScopeId; routeId?: RouteId; routePath?: string; routeLabel?: string; collections: ScopeCollection[];}5.7 Navigation Map
Section titled “5.7 Navigation Map”interface RouteActivation { kind: "path" | "action" | "app_defined"; value: string; // z. B. "/contacts" oder "nav.contacts.open"}
interface NavigationRoute { id: RouteId; path: string; // z. B. "/contacts" oder "/contacts/:id" label?: string; entities?: EntityType[]; capabilities?: string[]; activation?: RouteActivation;}
interface NavigationMap { revision?: Revision; routes: NavigationRoute[];}5.7.1 Execution Model for Navigation
Section titled “5.7.1 Execution Model for Navigation”The Navigation Map is descriptive. It does not define its own mutation or navigation channel.
If an agent wants to switch to a route, this SHOULD happen via the existing Action Runtime.
Recommended mapping:
activation.kind = "path"— the consumer SHOULD execute an existing navigation action, typicallynav.navigate, addressing the route viaNavigationRoute.id,NavigationRoute.path, or an app-defined runtime binding.activation.kind = "action"— the consumer SHOULD execute the declared action referenced inactivation.valueviaaction.request.activation.kind = "app_defined"— the concrete execution is app-specific and MUST only occur if a matching declared capability or action is present.
Agent Cognition deliberately does not define a separate message type such as uiap.cognition.navigate.
5.8 Bootstrap Document
Section titled “5.8 Bootstrap Document”interface CognitionBootstrap { revision?: Revision; schema?: EntitySchemaDocument; navigation?: NavigationMap; context?: ScopeContext;}6. Availability Model
Section titled “6. Availability Model”6.1 Fundamental Rule
Section titled “6.1 Fundamental Rule”Agent Cognition clearly distinguishes between:
- Schema knowledge: Which entities and fields exist?
- Record knowledge: Which concrete records and field values are currently available?
These two levels MUST be considered separately.
6.2 Default for Records
Section titled “6.2 Default for Records”If an app declares nothing else:
- The schema MAY be delivered in full.
- Records MAY only be delivered within the current scope and only if visible.
recordAccessis implicitlyvisible_only.
6.3 recordAccess Semantics
Section titled “6.3 recordAccess Semantics”visible_only
Section titled “visible_only”- Only currently visible records MAY be delivered.
- Querying outside the visible range MUST NOT occur.
- An agent SHOULD in this case use the Navigation Map to switch to the relevant route or list.
scope_window
Section titled “scope_window”- The app MAY deliver a limited logical list range in addition to the visible viewport.
- Typical cases are virtualization, pagination, or lazy loading.
- Filtering outside the already declared scope logic MUST NOT occur freely.
queryable
Section titled “queryable”- The app MAY allow limited read-only queries.
- Queries MUST be bound to a scope or route.
- Queries MUST respect limits, redaction, and policy rules.
7. Negotiation and Bootstrap
Section titled “7. Negotiation and Bootstrap”7.1 Extension ID
Section titled “7.1 Extension ID”This specification uses the Extension ID:
"uiap.cognition"7.2 Handshake via ext
Section titled “7.2 Handshake via ext”Extension-specific handshake data is transported in the envelope field ext.
7.3 Offer in session.initialize
Section titled “7.3 Offer in session.initialize”interface CognitionInitializeExt { bootstrapDelivery?: "inline" | "deferred" | "none"; requestedSurfaces?: CognitionSurface[]; // Default: ["schema", "navigation", "context"] requestedQuery?: boolean; // Default: false}7.4 Selection in session.initialized
Section titled “7.4 Selection in session.initialized”interface CognitionInitializedExt { bootstrapDelivery: "inline" | "deferred" | "none"; enabledSurfaces: CognitionSurface[]; queryEnabled?: boolean; maxQueryLimit?: number; // empfohlen: <= 50 bootstrap?: CognitionBootstrap; // nur bei bootstrapDelivery="inline"}7.5 Rules
Section titled “7.5 Rules”- If
uiap.cognitionwas not negotiated, nouiap.cognition.*messages MUST be processed. - If
bootstrapDelivery = "inline"is selected,bootstrapMAY be included directly insession.initialized.ext["uiap.cognition"]. - If
bootstrapDelivery = "deferred"is selected, the agent SHOULD useuiap.cognition.bootstrap.get. requestedSurfacesSHOULD default to["schema", "navigation", "context"]when absent.queryEnabledMUST be explicitlytruebeforeuiap.cognition.queryMAY be used.
8. Message Types
Section titled “8. Message Types”8.1 uiap.cognition.bootstrap.get
Section titled “8.1 uiap.cognition.bootstrap.get”Requests Cognition data after session establishment.
Request
Section titled “Request”interface CognitionBootstrapGetPayload { include?: CognitionSurface[]; // Default: alle aktivierten Surfaces}Response: uiap.cognition.bootstrap
Section titled “Response: uiap.cognition.bootstrap”interface CognitionBootstrapPayload extends CognitionBootstrap {}- If
includeis absent, all enabled surfaces MUST be delivered. - Surfaces that are not enabled MUST NOT be delivered.
- If only non-enabled surfaces are requested, an
errorwithcode="capability_unavailable"or a namespaced Cognition error MUST be returned.
8.2 uiap.cognition.changed
Section titled “8.2 uiap.cognition.changed”Reports changed Cognition data.
interface CognitionChangedPayload { revision: Revision; changed: CognitionSurface[]; reason?: "route_change" | "data_change" | "selection_change" | "configuration" | string; bootstrap: CognitionBootstrap;}- In v0.1,
uiap.cognition.changedMUST deliver a full replacement object for each surface listed inchanged. - Receivers SHOULD fully replace the affected surfaces.
uiap.cognition.changedis intended for coarse-grained semantic changes, not for high-frequency UI churn at the element level.- Fine-grained UI changes SHOULD continue to be handled primarily via
web.state.deltaor other profile-specific delta mechanisms. - Publishers SHOULD batch multiple fine-grained changes and only emit
uiap.cognition.changedwhen schema, navigation, or scope context have changed in a semantically relevant way. - For large collections,
context.collections[].itemsSHOULD remain limited to the currently visible or declared window range. - Query results are considered transient response data in v0.1 and MUST NOT be automatically republished via
uiap.cognition.changed. - Typical triggers are route changes, filter/sort changes, collection membership changes, or configuration changes.
Note: Delta-based Cognition updates MAY be added as a separate message type in a future version.
8.3 uiap.cognition.query
Section titled “8.3 uiap.cognition.query”Executes a limited read-only query within a scope or route.
Request
Section titled “Request”interface CognitionQueryPayload { entity: EntityType; scopeId?: ScopeId; // Default: aktueller Scope routeId?: RouteId; // optionaler Route-Bezug filters?: FilterSpec[]; // implizites AND sort?: SortSpec[]; offset?: number; // Default: 0 limit?: number; // Default: app-definiert fields?: FieldName[]; // optionaler Feld-Subset}Response: uiap.cognition.query.result
Section titled “Response: uiap.cognition.query.result”interface CognitionQueryResultPayload { entity: EntityType; scopeId?: ScopeId; routeId?: RouteId; offset: number; limit: number; returned: number; totalCount?: number; hasMore?: boolean; items: EntityRecord[];}uiap.cognition.queryMUST only be used whenqueryEnabled = true.- Queries MUST remain bound to an active scope or a declared route.
- Queries MUST refer to exactly one
entitytype. - Queries MUST NOT contain joins, transitive relation resolution, or free script expressions.
- If the
recordAccessof the relevant entity type or scope collection is not at leastqueryable, the request MUST fail. - The app MUST enforce an effective maximum value for
limit. - Fields with
exposure = "declared_only"MUST NOT appear initems.fields. - Fields with
exposure = "redacted"MAY be masked, omitted, or marked as withheld inredactions. - Query results MUST use
source = "query". - A query MAY be restricted to directly related records by filtering on a declared relation field, e.g.
deal.contactId = c1. - Such direct relation-bound filters are not considered a join or transitive relation resolution.
- Multi-hop traversal, reverse expansion, nested includes, or automatic relation-following semantics are not defined in v0.1.
- Fields with
exposure = "declared_only"MAY be filterable if the app allows it, but MUST still be omitted fromitems.fields.
9. Error Codes
Section titled “9. Error Codes”This extension MAY use additional, namespaced error codes.
Recommended error codes:
type CognitionErrorCode = | "uiap.cognition.unknown_entity" | "uiap.cognition.unknown_scope" | "uiap.cognition.query_not_allowed" | "uiap.cognition.route_required" | "uiap.cognition.ambiguous_entity";10. Binding to Actions and Runtime
Section titled “10. Binding to Actions and Runtime”10.1 Goal
Section titled “10.1 Goal”An agent SHOULD be able to not only read entities but also reference them unambiguously when needed, so that Action specifications can use more precise targets.
10.2 Reusable Target Structure
Section titled “10.2 Reusable Target Structure”interface CognitionTarget { entityRef: EntityRef; targetRef?: string; // optionaler UI-Target-Bezug}10.3 Rules
Section titled “10.3 Rules”- Action/Runtime specifications MAY support
entityRefas an additional or alternative target. - If
entityRefandtargetRefare used together, both MUST point to the same underlying entity. - If resolving an
entityRefis ambiguous or stale, the action MUST fail withstate_conflict,bad_request, oruiap.cognition.ambiguous_entity. - Support for
entityRefonly extends target precision; it does not grant additional permissions. - Mutations remain normatively defined in Action/Runtime specifications.
11. Security and Privacy Considerations
Section titled “11. Security and Privacy Considerations”- Secure Default.
recordAccessSHOULD default tovisible_only. - Schema does not equal data disclosure. A field MAY be visible in the schema without its values ever being delivered.
- Field Exposure.
declared_onlyandredactedSHOULD be used for sensitive fields such asemail,phone, or internal IDs. - Query Limits. Implementations SHOULD use conservative limits; 50 records per query is a reasonable upper recommendation for v0.1.
- Audit. Apps SHOULD be able to document which scope queries and Cognition bootstrap data were delivered to agents.
- Least Surprise. If the agent is not permitted to see a record, that record SHOULD not be reconstructable implicitly through unexplained counts or side channels.
12. Profile Mapping
Section titled “12. Profile Mapping”This specification is profile-neutral.
A web profile MAY derive the visible entity records from DOM annotations, for example. Recommended attribute names are:
data-uiap-entitydata-uiap-entity-iddata-uiap-fielddata-uiap-collectiondata-uiap-primarydata-uiap-redact
The concrete normative definition of these attributes SHOULD occur in the respective profile, not in Core.
13. Examples
Section titled “13. Examples”13.1 Handshake with Inline Bootstrap
Section titled “13.1 Handshake with Inline Bootstrap”Request
Section titled “Request”{ "uiap": "0.1", "kind": "request", "type": "session.initialize", "id": "msg_1", "ts": "2026-03-29T09:00:00.000Z", "source": { "role": "agent", "id": "agent-runtime" }, "payload": { "supportedVersions": ["0.1"], "supportedExtensions": [ { "id": "uiap.cognition", "versions": ["0.1"], "required": false } ], "capabilityDelivery": "deferred", "peer": { "role": "agent", "name": "cascade-agent", "version": "0.1.0", "locale": "de-CH", "timezone": "Europe/Zurich" } }, "ext": { "uiap.cognition": { "bootstrapDelivery": "inline", "requestedSurfaces": ["schema", "navigation", "context"], "requestedQuery": false } }}Response
Section titled “Response”{ "uiap": "0.1", "kind": "response", "type": "session.initialized", "id": "msg_2", "correlationId": "msg_1", "sessionId": "sess_123", "ts": "2026-03-29T09:00:00.040Z", "source": { "role": "app", "id": "cascade-crm" }, "payload": { "sessionId": "sess_123", "selectedVersion": "0.1", "selectedExtensions": [ { "id": "uiap.cognition", "version": "0.1" } ], "capabilityDelivery": "deferred", "heartbeatMs": 15000 }, "ext": { "uiap.cognition": { "bootstrapDelivery": "inline", "enabledSurfaces": ["schema", "navigation", "context"], "queryEnabled": false, "bootstrap": { "schema": { "revision": "schema_1", "entities": { "contact": { "label": "Kontakt", "primaryField": "name", "recordAccess": "visible_only", "fields": { "name": { "type": "string", "searchable": true, "sortable": true }, "company": { "type": "string", "searchable": true }, "status": { "type": "enum", "enumValues": ["active", "inactive", "prospect"] }, "email": { "type": "email", "exposure": "declared_only" } } } } }, "navigation": { "revision": "nav_1", "routes": [ { "id": "contacts", "path": "/contacts", "label": "Kontakte", "entities": ["contact"], "capabilities": ["list", "search", "create"], "activation": { "kind": "path", "value": "/contacts" } } ] }, "context": { "revision": "ctx_7", "scopeId": "contacts-list", "routeId": "contacts", "routePath": "/contacts", "routeLabel": "Kontakte", "collections": [ { "entity": "contact", "access": "visible_only", "visibleCount": 2, "items": [ { "ref": { "type": "contact", "id": "c1", "stableId": "uiap-contact-c1", "primaryText": "Elena Rossi" }, "fields": { "name": "Elena Rossi", "company": "TechNova AG", "status": "active" }, "source": "visible" }, { "ref": { "type": "contact", "id": "c2", "stableId": "uiap-contact-c2", "primaryText": "Daniel Meier" }, "fields": { "name": "Daniel Meier", "company": "Nordstern GmbH", "status": "inactive" }, "source": "visible" } ] } ] } } } }}13.2 Limited Query
Section titled “13.2 Limited Query”Request
Section titled “Request”{ "uiap": "0.1", "kind": "request", "type": "uiap.cognition.query", "id": "msg_41", "sessionId": "sess_123", "ts": "2026-03-29T09:05:00.000Z", "source": { "role": "agent", "id": "agent-runtime" }, "requires": ["uiap.cognition"], "payload": { "entity": "contact", "scopeId": "contacts-list", "filters": [ { "field": "status", "op": "eq", "value": "inactive" } ], "sort": [ { "field": "name", "direction": "asc" } ], "offset": 0, "limit": 20 }}Response
Section titled “Response”{ "uiap": "0.1", "kind": "response", "type": "uiap.cognition.query.result", "id": "msg_42", "correlationId": "msg_41", "sessionId": "sess_123", "ts": "2026-03-29T09:05:00.015Z", "source": { "role": "app", "id": "cascade-crm" }, "requires": ["uiap.cognition"], "payload": { "entity": "contact", "scopeId": "contacts-list", "offset": 0, "limit": 20, "returned": 2, "totalCount": 2, "hasMore": false, "items": [ { "ref": { "type": "contact", "id": "c2", "primaryText": "Daniel Meier" }, "fields": { "name": "Daniel Meier", "company": "Nordstern GmbH", "status": "inactive" }, "source": "query" }, { "ref": { "type": "contact", "id": "c8", "primaryText": "Priya Shah" }, "fields": { "name": "Priya Shah", "company": "Aster Labs", "status": "inactive" }, "source": "query" } ] }}13.3 Navigation via Existing Action Runtime
Section titled “13.3 Navigation via Existing Action Runtime”Example of switching to the Contacts route via the existing runtime:
{ "uiap": "0.1", "kind": "request", "type": "action.request", "id": "msg_51", "sessionId": "sess_123", "ts": "2026-03-29T09:06:00.000Z", "source": { "role": "agent", "id": "agent-runtime" }, "payload": { "actionId": "nav.navigate", "target": { "ref": { "by": "route", "value": "contacts" } } }}13.4 Direct Relation Filter Without Join
Section titled “13.4 Direct Relation Filter Without Join”Example: Load all deals whose contactId points to contact c1.
{ "uiap": "0.1", "kind": "request", "type": "uiap.cognition.query", "id": "msg_61", "sessionId": "sess_123", "ts": "2026-03-29T09:07:00.000Z", "source": { "role": "agent", "id": "agent-runtime" }, "requires": ["uiap.cognition"], "payload": { "entity": "deal", "routeId": "deals", "filters": [ { "field": "contactId", "op": "eq", "value": "c1" } ], "limit": 20 }}This is a direct filter on a declared relation field in v0.1, but not a general relation traversal.
14. Conformance
Section titled “14. Conformance”A UIAP Agent Cognition v0.1-conformant implementation MUST, if it offers this extension:
- negotiate the extension cleanly
- be able to deliver
CognitionBootstrapininlineordeferredform - respect
recordAccess - respect
FieldExposure - send
uiap.cognition.changedas full replacement for changed surfaces - process
uiap.cognition.queryas read-only and limited when query mode is enabled
An implementation does not need to support all surfaces or querying to be conformant.
Normative References
Section titled “Normative References”- [RFC2119] Key words for use in RFCs to Indicate Requirement Levels, BCP 14
Changelog
Section titled “Changelog”| Version | Date | Changes |
|---|---|---|
| 0.1 | 2026-03-29 | Initial draft |