UIAP Capability Model
UIAP Capability Model v0.1
Abschnitt betitelt „UIAP Capability Model v0.1“| Feld | Wert |
|---|---|
| Status | Draft |
| Version | 0.1 |
| Datum | 2026-03-27 |
| Abhängigkeiten | — |
| Editoren | Patrick |
1. Zweck
Abschnitt betitelt „1. Zweck“Das Capability Model beschreibt was eine Anwendung semantisch darstellen, beobachten und ausführen kann.
Es trennt dabei sauber:
- Rollen: was ein UI-Ding ist
- Zustände: in welchem Zustand es ist
- Affordances: welche Interaktionen es grundsätzlich anbietet
- Actions: welche standardisierten Requests der Agent senden kann
- Risk: wie stark eine Aktion reguliert werden muss
- Success Signals: woran Erfolg erkennbar ist
Das ist der Unterschied zwischen „da ist irgendein Button“ und „das ist video.submit, aktivierbar, confirm-pflichtig, Erfolg = Route springt und Toast erscheint“.
2. Allgemeine Modellregeln
Abschnitt betitelt „2. Allgemeine Modellregeln“- Capability-Werte SOLLTEN stabil und maschinenlesbar sein.
- Core-Werte sind unpräfixiert reserviert.
- Vendor-/App-spezifische Erweiterungen SOLLTEN mit
x.beginnen, z. B.x.videoland.asset-card. - Ein Capability-Dokument KANN nur einen Teil des Core-Vokabulars unterstützen; die tatsächlich unterstützten Werte MÜSSEN explizit deklariert werden.
- Rollen und Affordances beschreiben Semantik, nicht konkrete DOM-Strukturen oder CSS.
3. Basis-Typen
Abschnitt betitelt „3. Basis-Typen“type StableId = string; // stabile, app-definierte Ziel-IDtype ScopeId = string; // logischer Bereich, z. B. "create-video-dialog"type ActionId = string; // z. B. "ui.activate" oder "video.create"3.1 Zielreferenz
Abschnitt betitelt „3.1 Zielreferenz“type TargetRef = | { by: "stableId"; value: StableId } | { by: "scope"; value: ScopeId } | { by: "route"; value: string } | { by: "semantic"; role: UIRole; name?: string; scope?: ScopeId } | { by: "custom"; value: string };4. UI-Rollen
Abschnitt betitelt „4. UI-Rollen“UIRole ist die kanonische Typisierung sichtbarer oder interaktiver UI-Objekte.
type UIRole = // App / Struktur | "app" | "route" | "region" | "group" | "form" | "dialog" | "drawer" | "popover" | "tabpanel"
// Navigation / Strukturierte Auswahl | "link" | "menu" | "menuitem" | "tablist" | "tab" | "toolbar" | "breadcrumb" | "pagination"
// Collections | "list" | "listitem" | "table" | "row" | "cell" | "grid" | "tree" | "treeitem"
// Inputs / Controls | "button" | "textbox" | "textarea" | "searchbox" | "combobox" | "listbox" | "option" | "checkbox" | "radio" | "switch" | "slider" | "spinbutton" | "datepicker" | "timepicker" | "fileinput" | "label"
// Feedback / Status | "alert" | "toast" | "status" | "progress" | "spinner"
// Medien / Spezialfälle | "image" | "video" | "audio" | "canvas"
// Escape hatch | "custom";4.1 Rollensemantik
Abschnitt betitelt „4.1 Rollensemantik“button: aktivierbarer Befehltextbox/textarea: editierbare Texteingabecheckbox/radio/switch: diskrete Zustandswahlcombobox/listbox/option: Auswahl aus Kandidatendialog/drawer/popover: temporäre UI-Oberflächentoast/alert/status: beobachtbare Rückmeldesignalecustom: nur wenn keine Core-Rolle passt
5. UI-Zustände
Abschnitt betitelt „5. UI-Zustände“UIState beschreibt den beobachtbaren Zustand eines Elements oder Scopes.
interface UIState { visible?: boolean; enabled?: boolean; focusable?: boolean; focused?: boolean; editable?: boolean; readonly?: boolean; required?: boolean;
busy?: boolean; loading?: boolean; blocked?: boolean;
selected?: boolean; checked?: boolean | "mixed"; pressed?: boolean; expanded?: boolean; open?: boolean; modal?: boolean;
hovered?: boolean; dragged?: boolean;
current?: false | "page" | "step" | "location" | "date" | "time"; invalid?: false | true | "grammar" | "spelling";
multiline?: boolean; hasPopup?: false | "menu" | "listbox" | "dialog" | "grid" | "tree"; orientation?: "horizontal" | "vertical";
textValue?: string; numericValue?: number; min?: number; max?: number; step?: number;
placeholder?: string; description?: string;
sensitive?: boolean; obscured?: boolean;}5.1 Zustandsschlüssel
Abschnitt betitelt „5.1 Zustandsschlüssel“Ein Capability-Dokument SOLLTE zusätzlich deklarieren, welche Zustandsschlüssel aktiv emittiert werden.
type UIStateKey = keyof UIState;5.2 Zustandsregeln
Abschnitt betitelt „5.2 Zustandsregeln“visible=falseimpliziert nicht automatischenabled=false.blocked=truebedeutet: formal vorhanden, aber aktuell nicht verwendbar.sensitive=truemarkiert Daten oder Controls, die gesonderte Policy brauchen.obscured=truemarkiert verdeckte oder absichtlich maskierte Inhalte.
6. Affordances
Abschnitt betitelt „6. Affordances“Affordances beschreiben, welche Interaktionsart ein Element grundsätzlich anbietet.
type UIAffordance = | "read" | "focus" | "activate" | "edit" | "choose" | "toggle" | "expand" | "collapse" | "open" | "close" | "scroll" | "submit" | "dismiss" | "drag" | "drop" | "resize" | "upload" | "navigate" | "invoke";6.1 Affordance-Semantik
Abschnitt betitelt „6.1 Affordance-Semantik“activate: generische Aktivierung, z. B. Button, Link, Cardedit: Text oder Wert kann verändert werdenchoose: Auswahl aus Optionentoggle: binärer oder tri-state Wechselinvoke: fachliche App-Aktion jenseits eines reinen Klicks
6.2 Wichtige Trennung
Abschnitt betitelt „6.2 Wichtige Trennung“- Affordance = was ein Element prinzipiell anbietet
- Action = standardisierter Request des Agenten
Ein button hat typischerweise activate. Der Agent sendet dann z. B. ui.activate.
7. Actions
Abschnitt betitelt „7. Actions“Actions sind standardisierte ausführbare Operationen.
7.1 Primitive Actions
Abschnitt betitelt „7.1 Primitive Actions“type PrimitiveActionType = | "ui.read" | "ui.focus" | "ui.highlight" | "ui.hover" | "ui.activate" | "ui.enterText" | "ui.clearText" | "ui.setValue" | "ui.choose" | "ui.toggle" | "ui.expand" | "ui.collapse" | "ui.open" | "ui.close" | "ui.scrollIntoView" | "ui.scroll" | "ui.submit" | "ui.upload" | "nav.navigate" | "app.invoke";7.2 Execution Modes
Abschnitt betitelt „7.2 Execution Modes“type ExecutionMode = | "appAction" // direkte App-Funktion / Registry | "semanticUi" // semantische UI-Zieladressierung | "inputSynthesis" // synthetische Pointer/Keyboard-Eingaben | "externalDriver" // externer Automation-Driver | "visionAssist"; // vision-gestützter Fallback7.3 Action Descriptor
Abschnitt betitelt „7.3 Action Descriptor“interface ActionDescriptor { id: ActionId; // "ui.activate" oder "video.create" kind: "primitive" | "domain"; title?: string; description?: string;
targetKinds: Array<"element" | "scope" | "route" | "entity" | "session" | "none">; requiredAffordances?: UIAffordance[]; executionModes: ExecutionMode[];
args?: ActionArgDescriptor[]; idempotency?: "idempotent" | "conditional" | "non_idempotent";
risk: RiskDescriptor; success?: SuccessSignal[];
metadata?: Record<string, unknown>;}interface ActionArgDescriptor { name: string; type: "string" | "number" | "boolean" | "enum" | "object" | "array"; required?: boolean; enum?: string[]; description?: string;}7.4 Domain Actions
Abschnitt betitelt „7.4 Domain Actions“Neben den Primitive Actions DARF eine Anwendung fachliche Actions deklarieren, z. B.:
video.createworkspace.setupteam.invitebilling.openSettings
Diese SOLLTEN stabil, punkt-segmentiert und domänensemantisch benannt sein.
8. Risk Model
Abschnitt betitelt „8. Risk Model“Hier wird es absichtlich sauber getrennt, weil Menschen sonst dazu neigen, fünf völlig verschiedene Risiken in ein einziges Wort zu quetschen.
8.1 Effektiver Risk Level
Abschnitt betitelt „8.1 Effektiver Risk Level“RiskLevel steuert die Ausführbarkeit.
type RiskLevel = | "safe" // autonom innerhalb gewährter Scopes ausführbar | "confirm" // explizite Nutzerbestätigung nötig | "blocked"; // nicht automatisch ausführbar8.2 Risk Tags
Abschnitt betitelt „8.2 Risk Tags“RiskTag beschreibt die fachliche Ursache oder Klasse des Risikos.
type RiskTag = | "sensitive_data" | "destructive" | "external_effect" | "privileged" | "billing" | "security" | "identity" | "legal" | "irreversible";8.3 Risk Descriptor
Abschnitt betitelt „8.3 Risk Descriptor“interface RiskDescriptor { level: RiskLevel; tags?: RiskTag[]; reason?: string;}8.4 Risk-Semantik
Abschnitt betitelt „8.4 Risk-Semantik“safe: z. B. Route öffnen, Tab wechseln, Textvorschlag in Entwurf schreibenconfirm: z. B. Datensatz anlegen, Einladung versenden, Settings speichernblocked: z. B. Passwort ändern, Zahlung auslösen, Benutzer löschen, irreversible Publish-Aktion
8.5 Risk-Regeln
Abschnitt betitelt „8.5 Risk-Regeln“- Wenn mehrere Risk Tags zutreffen, gewinnt der strengste
level. blockedDARF nicht autonom ausgeführt werden.confirmSOLLTE vor Ausführung einen menschlichen Bestätigungspunkt verlangen.
9. Success Signals
Abschnitt betitelt „9. Success Signals“Success Signals sind beobachtbare Prädikate, keine Wünsche und kein promptiger Aberglaube.
9.1 Signal-Klassen
Abschnitt betitelt „9.1 Signal-Klassen“type SuccessSignal = | { kind: "element.appeared"; target: TargetRef } | { kind: "element.disappeared"; target: TargetRef } | { kind: "element.state"; target: TargetRef; state: Partial<UIState> } | { kind: "value.equals"; target: TargetRef; value: string | number | boolean } | { kind: "route.changed"; pattern?: string; exact?: string } | { kind: "dialog.opened"; target?: TargetRef } | { kind: "dialog.closed"; target?: TargetRef } | { kind: "toast.contains"; text: string } | { kind: "status.contains"; text: string } | { kind: "validation.none"; scope?: ScopeId } | { kind: "collection.count"; target: TargetRef; op: "eq" | "gte" | "lte"; value: number } | { kind: "entity.created"; entityType: string; idPath?: string } | { kind: "entity.updated"; entityType: string; idPath?: string } | { kind: "entity.deleted"; entityType: string; idPath?: string } | { kind: "network.response"; urlPattern?: string; status?: number } | { kind: "custom"; name: string; payload?: Record<string, unknown> };9.2 Signal-Regeln
Abschnitt betitelt „9.2 Signal-Regeln“- Signals SOLLTEN deklarativ und beobachtbar sein.
- Ein Action Descriptor SOLLTE mindestens einen erwarteten Success Signal enthalten.
customSOLLTE nur genutzt werden, wenn kein Core-Signal passt.- Für kritische Domain Actions SOLLTEN mehrere Success Signals kombiniert werden.
Beispiel: video.create
route.changedauf/videos/:idtoast.contains = "erstellt"- optional
entity.created = "video"
10. Capability Document
Abschnitt betitelt „10. Capability Document“Das Capability-Dokument ist die Gesamtbeschreibung der aktiven Fähigkeiten.
interface CapabilityDocument { modelVersion: "0.1";
roles: UIRole[]; stateKeys: UIStateKey[]; affordances: UIAffordance[];
actions: ActionDescriptor[];
riskLevels: RiskLevel[]; riskTags?: RiskTag[];
successSignalKinds: string[];
metadata?: Record<string, unknown>;}10.1 Regeln
Abschnitt betitelt „10.1 Regeln“roles,stateKeys,affordances,actions,riskLevelsMÜSSEN vorhanden sein.- Eine App MUSS nur tatsächlich unterstützte Werte deklarieren.
successSignalKindsSOLLTE alle im Dokument genutztenkind-Werte enthalten.
11. Beispiel eines Capability-Dokuments
Abschnitt betitelt „11. Beispiel eines Capability-Dokuments“{ "modelVersion": "0.1", "roles": [ "route", "dialog", "form", "button", "textbox", "textarea", "toast", "status" ], "stateKeys": [ "visible", "enabled", "focused", "required", "open", "invalid", "textValue", "sensitive" ], "affordances": [ "read", "focus", "activate", "edit", "submit", "navigate", "invoke" ], "actions": [ { "id": "ui.activate", "kind": "primitive", "targetKinds": ["element"], "requiredAffordances": ["activate"], "executionModes": ["appAction", "semanticUi", "inputSynthesis"], "risk": { "level": "safe" } }, { "id": "ui.enterText", "kind": "primitive", "targetKinds": ["element"], "requiredAffordances": ["edit"], "executionModes": ["appAction", "semanticUi", "inputSynthesis"], "args": [ { "name": "text", "type": "string", "required": true } ], "risk": { "level": "safe" } }, { "id": "video.create", "kind": "domain", "title": "Video erstellen", "targetKinds": ["scope"], "executionModes": ["appAction", "semanticUi"], "args": [ { "name": "title", "type": "string", "required": true }, { "name": "useCase", "type": "string", "required": false } ], "idempotency": "non_idempotent", "risk": { "level": "confirm", "tags": ["external_effect"] }, "success": [ { "kind": "route.changed", "pattern": "/videos/:id" }, { "kind": "toast.contains", "text": "erstellt" } ] } ], "riskLevels": ["safe", "confirm", "blocked"], "riskTags": [ "sensitive_data", "destructive", "external_effect", "privileged" ], "successSignalKinds": [ "route.changed", "toast.contains", "element.state", "validation.none" ]}Normative Referenzen
Abschnitt betitelt „Normative Referenzen“- [UIAP-CORE] UIAP Core v0.1
- [RFC2119] Key words for use in RFCs to Indicate Requirement Levels, BCP 14
Security Considerations
Abschnitt betitelt „Security Considerations“- Capability-Dokumente KÖNNEN sicherheitsrelevante Informationen enthalten (z.B. verfügbare Admin-Actions). Der Zugang zu Capability-Informationen SOLLTE auf autorisierte Agenten beschränkt sein.
- Risk-Level MÜSSEN korrekt deklariert werden; eine falsche Einstufung kann zu unbeabsichtigten Aktionen führen.
- Sensitive Felder SOLLTEN im Capability-Dokument als solche markiert sein.
Changelog
Abschnitt betitelt „Changelog“| Version | Datum | Änderungen |
|---|---|---|
| 0.1 | 2026-03-27 | Initialer Entwurf |