a2ui-project / a2ui-project/a2ui

[FEATURE]: Declare semantic action class on interactive components

Offen
#2,197 4 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
status: first-line-handled status: needs-team-input status: needs-triage
Vorherrschende Sprache
TypeScript
Sterne
16.4k
Forks
1.3k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
134

Beschreibung

- [x] I have searched the existing issues to make sure this is not a duplicate.

## Is your feature request related to a problem? Please describe.

The closed catalog eliminates code execution and markup injection, which is the
right foundation. But interactive components declare only a *visual* variant,
never their *semantic* intent:

- `Button.variant`: `default` | `primary` | `borderless`
- `TextField.variant`: `longText` | `number` | `shortText` | `obscured`

Per `specification/v0_9_1/catalogs/basic/catalog.json`, no component in the basic
catalog carries a role, importance, or destructiveness indicator. The v1.0
candidate adds `actionResponse` / `actionId` / `callFunction`, but no action
semantics.

Two consequences:

**1. The deceptive-control threat class is unrepresentable, not merely
unenforced.** The published MAESTRO threat model for AG-UI/A2UI names Layer 7
"UI Confusion / Deceptive Interfaces", with the example of a "View Details"
button that triggers deletion. Detecting that requires comparing a control's
declared semantics against its label. With only an opaque event name and a
visual variant there is nothing to compare against, so a conforming validator
cannot detect the shape at all.

**2. Human-in-the-loop approval gates have nothing to key on.** A host that wants
to route destructive actions to a confirmation step, or an audit record that
wants to state a destructive action was presented, must first identify which
actions are destructive. That never crosses the wire today, leaving hosts to
infer intent by matching event-name strings the agent itself chooses.

Concretely: I ported a set of nine generative-UI trust conformance vectors to
v0.9.1. Six port cleanly. Three are inexpressible, all for this single reason.

## Describe the solution you'd like

An **optional** semantic class on components carrying an action. Optional means
purely additive — not a breaking change to the candidate spec, and renderers
that ignore it behave exactly as today.

```json
{
"id": "delete-btn",
"component": "Button",
"child": "delete-label",
"role": "destructive",
"action": { "event": { "name": "delete_account", "context": {} } }
}
```

Minimal viable enum:

| value | meaning |
|---|---|
| `neutral` | default; no declared semantics (current behaviour) |
| `confirm` | affirmative, non-destructive |
| `cancel` | backs out without effect |
| `destructive` | irreversible effect |

`approve` / `reject` / `submit` could be added if useful or collapsed into
`confirm` / `cancel`. The minimum that unlocks policy is the
affirmative / negative / destructive distinction.

This lets a renderer or a policy layer above it:

- reject a label that contradicts its declared role, before render
- route `destructive` to a confirmation step, or deny it by host policy
- record in an audit trail what class of action a user was actually shown

## Describe alternatives you've considered

- **Label heuristics alone** — inspect the Button's child `Text` for destructive
words. This is what a policy layer must do today and it is weak: the label is
exactly the surface an injected agent controls, it is language-specific, and
with no second signal it cannot distinguish mislabeled from honestly labeled.
- **Host-side allow-list of event names** — brittle, doesn't generalize, and
every host maintains its own list of names the agent picks.
- **Custom catalogs with semantic components** — works, but fragments the
ecosystem and loses the portability that motivates a framework-agnostic spec.
- **Do nothing** — leaves a named threat class structurally undetectable and
leaves every host to reinvent the same inference layer.

## Additional context

Conformance vectors, including the six that port cleanly and the three that
don't, with per-vector reasoning:
https://github.com/punarduttrajput/wovyr/tree/main/generative-ui-conformance/a2ui

Caveat stated up front: those A2UI frames were constructed against
`catalog.json` and the shipped example gallery, and are **not yet validated
against a live renderer**. If any fails to validate, that is a bug in the
vectors and I would like to know.

A related but separate concern I would rather not conflate here: the basic
catalog's own `examples/09_login-form.json` is structurally a credential-
collecting surface, and nothing in the wire format distinguishes an agent
legitimately rendering it from an injected agent rendering the same thing. That
is a question about surface provenance rather than action semantics — happy to
file it separately if useful.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Review the specification files, especially spec/v0_9_1/catalogs/basic/catalog.json and the v1.0 candidate spec. Understand the component structure and where action semantics could be added. Examine the example gallery and the linked conformance vectors to see the missing detection capability. The change involves updating the spec and likely the TypeScript types defining components.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
json, typescript
Bereich
backend-api-design, security
Issue-Typ
Feature
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Aktiv
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.