Optionaler Aktionslebenszyklus
ci-action-lifecycle/v1 · gemeinsames UI-Modul 1.0.0
# Optionaler Aktionslebenszyklus: ci-action-lifecycle/v1
Für bewusst ausgewählte langsamere Aktionen, etwa Aktualisieren, Filtern oder
Ansicht laden. Keine automatische Migration bestehender Apps. Die vorherige
Button-Guideline bleibt als Bedienprinzip gültig; diese Referenz beschreibt die
nun vorhandene gemeinsame Implementierung und ihre Transportgrenzen.
## Gemeinsame Quelle und Version
Öffentlicher Vertrag und Dateien:
https://mcp-lab.christian-igel.tech/xp-contract/actions/v1/
UI-Modul **1.0.0**: `action-lifecycle.mjs`, `xp-action-lifecycle.css` sowie das
lokal lauffähige `example.html`. Manifest und SHA-256 prüfen, Assets lokal in die
App bündeln; keine Hotlinks und keine CSP-Lockerung. Die Foundation liefert die
gleichen Assets unter `mcp_foundation/ui/action-lifecycle/` aus. Native Python-
Unterstützung ab `mcp-foundation-python 1.5.0a10`; eine vorhandene Paketversion
allein beweist keine Ende-zu-Ende-Unterstützung im Host oder Benutzerclient.
XP-Presentation bleibt **1.1.0**; dessen Version aktiviert keine Aktionsfähigkeit.
## Annahme, Leben, Fortschritt und Abschluss
- Sofort nach dem Klick lokal `waiting` anzeigen. Das bedeutet nur: App wartet.
- `accepted` erst aus echter Annahme nach Schema- und Rechteprüfung ableiten.
- `alive` ist ein echtes Lebenszeichen derselben noch laufenden Invocation.
- `progress` nur aus tatsächlich gemeldetem Fortschritt darstellen; keine
erfundenen Prozentwerte oder Timer als Fortschritt ausgeben.
- Die fachliche Endantwort und ihre erfolgreiche Übernahme sind maßgeblich.
Ereignisse schließen nichts ab. Fehler schlagen Erfolgsmetadaten; eine
`started`-Jobquittung bedeutet gestartet, niemals fachlich fertig.
## Capability und Korrelation
Namespace `tech.christian-igel/action-lifecycle` (NS), Vertragsversion integer 1.
Capability `{version:1,events:['accepted','alive','progress'],cancel:'local'}`
auf beiden Seiten ausdrücklich aushandeln. Native MCP SDK 2.2 verwendet
`capabilities.extensions[NS]`; MCP Apps/AppBridge verwendet
`capabilities.experimental[NS]` und der XP-Host spiegelt die ausgehandelte
Fähigkeit zusätzlich in `getHostContext()[NS]`. Die UI-Ressource optiert über
`_meta[NS]` ein. Diese Container nicht austauschbar behandeln.
Aufrufe tragen `params._meta[NS]={version:1,operationId}`. Toolargumente bleiben
unverändert. OperationId: eindeutig, maximal 128 Zeichen aus `[A-Za-z0-9._:-]`.
Eigene Annahme-/Alive-Notifications heißen
`notifications/tech.christian-igel/action-lifecycle`, Params:
`{version:1,operationId,sequence,event:'accepted'|'alive',message?}`.
Fortschritt läuft über natives `notifications/progress` mit dem ursprünglichen
`progressToken` und `_meta[NS]={version:1,operationId,sequence}`. Sequenz startet
bei 1 und steigt über Ereignisse und terminale Metadaten monoton.
Endantwort bleibt CallToolResult mit bestehenden content/structuredContent/
isError und optional `_meta[NS]={version:1,operationId,sequence,status}`;
status ist `success`, `error`, `cancelled` oder `started`. Falsche IDs, alte
Sequenzen, abgeschlossene oder durch Kontextwechsel ungültige Vorgänge ignorieren.
## Integration und Legacy-Verhalten
`createActionController` ist DOM-unabhängig. `createActionButtonBindings` bindet
Buttons und übernimmt Gesten sowie reservierte Geometrie. Beispiel:
```js
const buttons = createActionButtonBindings({
document,
capability: () => bridge.getHostContext()?.[NS],
getContext: () => identityEpoch,
isValid: () => !disposed,
});
buttons.prepare(button, {label: 'Aktualisieren'});
button.addEventListener('click', event => buttons.run(event, button, {
scope: 'results', label: 'Aktualisieren', resultRegion,
execute: ({signal, operationId, report}) => transportRead({signal, operationId, report}),
commit: data => renderResult(data),
}));
// Bei Rollen-, Konto-, Fenster- oder Navigationswechsel:
buttons.invalidate();
// Beim endgültigen Abbau:
buttons.dispose();
```
Capability spät/dynamisch auswerten, da Binding vor Handshake entstehen kann.
Transportadapter melden nur korrelierte echte Ereignisse; keine globale
Accountabfrage im Controller. Fachliches `commit` ist synchron. `prepare`
reserviert die Buttonfläche bereits vor dem ersten Klick.
WP-Provider-Streaming ist zusätzlicher Opt-in `responseMode:'action-stream-v1'`
mit Metadaten; Antwort `application/x-ndjson`. Notifications und genau eine
terminale Result- oder Fault-Frame, keine neue Queue. Ohne ausgehandelte
Unterstützung normales Legacy-JSON unverändert verwenden: sofortiges lokales
Warten bleibt möglich. **Kein Status-Polling als Fallback.** Nach Beginn eines
Toolaufrufs bei Transportfehler niemals über Legacy erneut ausführen. Streamende
ohne Endantwort bedeutet unbekannter Ausgang, nicht Erfolg oder Serverabbruch.
## Buttons, Abbruch und Grenzen
Erster Klick verändert den stabilen, fokussierten und weiterhin bedienbaren
Button sofort. Späterer Einzelklick beendet lokales Warten: Operation zuerst
invalidieren, dann bestmöglich AbortSignal senden. Späte Resultate und Fehler
können den Zustand nicht überschreiben. Neues Starten erhält eine neue ID.
Doppelklick einschließlich langsamer Zweitklicks nicht als Abbruch oder
Doppelstart werten; das gemeinsame Modul verwendet ein 1000-ms-Klärungsfenster.
Resultate während eines möglichen Abbruchklicks puffern. Tastaturautorepeat,
Enter/Space, Touch, Reduced Motion und Forced Colors gesondert prüfen.
**Transportabbruch bestätigt keinen Serverabbruch und macht keine Änderung
rückgängig.** Bei Schreibaktionen weder automatisches Retry noch Undo behaupten;
fachliches Idempotenz-, Bestätigungs- und Abbruchverfahren bleibt zuständig.
Ein laufender Hintergrundjob bleibt im vorhandenen Job-System mit seiner ID;
`started` bleibt eine Quittung. Der Aktionscontroller baut keine Jobverwaltung,
keine Pollingschleife und keinen neuen Hintergrundprozess.
## Nachweis
Je Consumer Capability/Legacy, sichtbare echte Phasen vor Endantwort, Korrelation,
späte Antworten, Abbruch, Doppelklick, Kontextwechsel und unveränderte Geometrie
prüfen. Paketkopie, technischer Harness und tatsächliche ChatGPT-/XP-Clientabnahme
sind getrennte Belege. Keine Unterstützung allein aus Skillinstallation ableiten.