From 0923454b57993c5f3c2542e64b6ec6aa67beefc7 Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Thu, 23 Apr 2026 23:10:02 +0200
Subject: [PATCH] docs
---
.../1-plan/2026-04-typed-generic-handover.md | 306 ++++++++++++++++++
.../2026-04-graph-editor-node-config-fixes.md | 204 ++++++++++++
...pwg-pilot-mietzinsbestaetigung-workflow.md | 14 +-
...-04-trustee-cleanup-positions-documents.md | 43 ++-
4 files changed, 543 insertions(+), 24 deletions(-)
create mode 100644 c-work/1-plan/2026-04-typed-generic-handover.md
create mode 100644 c-work/4-done/2026-04-graph-editor-node-config-fixes.md
rename c-work/{3-validate => 4-done}/2026-04-pwg-pilot-mietzinsbestaetigung-workflow.md (96%)
rename c-work/{1-plan => 4-done}/2026-04-trustee-cleanup-positions-documents.md (64%)
diff --git a/c-work/1-plan/2026-04-typed-generic-handover.md b/c-work/1-plan/2026-04-typed-generic-handover.md
new file mode 100644
index 0000000..482eff4
--- /dev/null
+++ b/c-work/1-plan/2026-04-typed-generic-handover.md
@@ -0,0 +1,306 @@
+
+
+
+
+# Typed Generic Handover für den Graphical Editor — Pick‑not‑Push, Static‑Only Schemas, Hard Validation
+
+## Beschreibung und Kontext
+
+Mit `2026-04-generic-graph-editor.md` (done) wurden ein typisiertes Port‑System (`portTypes.py`), generische `frontendTypeRenderers/` und ein schema‑basierter `DataPicker.tsx` eingeführt. Der zur Laufzeit wirksame Handover zwischen Nodes basiert dort jedoch weiterhin auf einem **Push‑Modell**: `actionNodeExecutor._wireHandover` ruft `INPUT_EXTRACTORS` (Heuristiken pro Schema‑Name) auf und füllt fehlende Parameter im Konsumer aus dem Output des direkten Vorgängers.
+
+Im PWG‑Pilot (`pwg-pilot-jahresmietzinsbestätigung.workflow.json`) zeigt dieses Modell mehrere Symptome:
+
+- `connectionReference` ist in den meisten Folge‑Nodes leer (`n4 sharepoint.downloadFile`, `n10 email.draftEmail`), wird zur Laufzeit erneut vom User abgefragt — Heuristik kennt `connectionReference` nicht.
+- KI versteht den Handover beim Modellieren nicht: das Output‑Schema (`DocumentList { documents }`) ist zu flach, Provenienz (Connection, Source‑Folder) fehlt — die KI kann keinen sauberen Pfad picken, sondern „rät".
+- Felder wie `attachmentBuilder` rendern als unstrukturierte Text‑Inputs (kein passender Renderer).
+- Loop‑Body‑Nodes können nicht sauber auf Vorgänger‑Kontext (z.B. SharePoint‑Label aus 1. Node) zurückgreifen.
+
+**Geschäftstreiber:** Solange der Handover nicht generisch deterministisch ist, sind sowohl AI‑gestütztes Workflow‑Modellieren als auch User‑Self‑Service unzuverlässig. Jede neue Node‑Kombination produziert neue Edge‑Cases. Das blockiert die operative Skalierung des Graphical Editors über den PWG‑Pilot hinaus.
+
+**Prinzipien‑Wechsel (Decisions vom 2026‑04‑23):**
+
+1. **Pick‑not‑Push:** Jeder Input‑Parameter ist explizit gebunden (DataRef / Static / SystemVar). Keine `INPUT_EXTRACTORS`‑Heuristik zur Laufzeit. Auto‑Suggest gibt es nur als Authoring‑Komfort beim Wire‑Connect.
+2. **Static‑Only Schemas:** Output‑Schemas sind entweder im Code‑Katalog (`PORT_TYPE_CATALOG`) oder als **graph‑defined Schema** im Workflow‑Graph fixiert (z.B. `input.form.fields`). Keine Runtime‑dynamischen Schemas (kein `ai.extractStructured`, kein `data.transform`).
+3. **Loop‑Scoping lexikalisch:** Im Loop‑Body sind alle lexikalisch sichtbaren Outer‑Nodes pickbar **plus** zusätzlich `loop.item`, `loop.index`, `loop.total`. Kein Magic‑Envelope.
+4. **Connection als Hybrid:** Source‑Nodes haben weiterhin einen `userConnection`‑Parameter mit Picker. Sie exponieren eine `ConnectionRef { id, authority, label }` (ohne Secrets) im Output. Downstream‑Nodes binden ihren `connectionReference` per DataRef gegen diese `ConnectionRef`.
+5. **Hard Validation:** Type‑Mismatch oder fehlende Required‑Bindung blockiert den Run vor Start.
+6. **Greenfield + Migrationsskript:** kein Heuristik‑Fallback. Bestehende Workflows werden einmalig automatisch migriert (deterministisch, weil die alte Heuristik selbst deterministisch ist).
+
+## Fokus und kritische Details
+
+### Was schon da ist (verifiziert im Code, 2026‑04‑23)
+
+- `gateway/modules/features/graphicalEditor/portTypes.py` — `PortField`, `PortSchema`, `PORT_TYPE_CATALOG`, `SYSTEM_VARIABLES`, `_normalizeToSchema`, `INPUT_EXTRACTORS`.
+- `gateway/modules/workflows/automation2/executors/actionNodeExecutor.py` — `_wireHandover()` (zu entfernen), `_resolveConnectionParam()` (bleibt im neuen Modell, Anwendung verschiebt sich).
+- `frontend_nyla/src/components/FlowEditor/nodes/shared/DataPicker.tsx` — schema‑basierte Pfad‑Auflösung mit Transit‑Chain, System‑Sektion.
+- `frontend_nyla/src/components/FlowEditor/nodes/frontendTypeRenderers/index.tsx` — `FRONTEND_TYPE_RENDERERS` Registry.
+- `frontend_nyla/src/components/FlowEditor/editor/NodeConfigPanel.tsx` — generischer Config‑Renderer.
+
+### Was fragil / kritisch wird
+
+- **`PORT_TYPE_CATALOG` ist heute zu flach.** `DocumentList` enthält nur `documents: List[Document]`, aber `Document` selbst ist nicht im Katalog typisiert. Folge: Picker kann nicht in einzelne Document‑Felder (z.B. `name`, `mimeType`, `downloadUrl`) reinpicken. Dasselbe gilt für `FileList`, `EmailList`, `TaskList`. → Alle List‑Schemas brauchen `itemSchema`, alle Item‑Typen brauchen eigene Einträge im Katalog.
+- **Loop‑Scope‑Berechnung im Frontend.** Heute sehr flach. Muss BFS rückwärts entlang `connections` plus transitive Loop‑Body‑Hierarchie berücksichtigen, ohne Performance‑Kollaps bei großen Graphen.
+- **Type‑Compat ist heute weich.** `validateGraph` warnt nur — neu: hart blockierend, plus klare Fehler‑UX im Frontend (rote Pills + Run‑Button disabled).
+- **Migration der bestehenden Workflows.** Deterministisch, weil `INPUT_EXTRACTORS` deterministisch sind — aber jede Node mit implizitem Wire‑Handover muss einen passenden DataRef bekommen. Trockenlauf mit Diff zwingend.
+- **`input.form` bleibt Sonderfall „graph‑defined Schema"** — nicht Runtime‑Dynamik, sondern „Schema lebt in `node.parameters.fields` und ist nach dem Speichern fix". Frontend & Backend lesen es deterministisch über eine gemeinsame Helper‑Funktion.
+
+### Bekannte Fallstricke
+
+- AI Agent Tool‑Generation: heute baut die KI Workflows oft mit leeren `connectionReference`‑Feldern und vertraut auf den Wire‑Handover. Nach dem Cut funktioniert das nicht mehr — Prompt + Tool‑Schemas müssen so geschärft werden, dass die KI explizite DataRefs erzeugt.
+- Pause/Resume‑Pfad in `executionEngine`: `initialNodeOutputs` (Resume‑User‑Eingabe) muss weiterhin gegen Output‑Schema validiert werden — passt nahtlos zum harten Validation‑Modus.
+- `flow.merge`, `flow.switch`, `flow.ifElse` — Transit‑Envelope bleibt; aber `Transit` darf kein Free‑Pass für Type‑Compat sein (Picker folgt Transit‑Chain, Validation prüft den realen Producer am Ende der Chain).
+- `attachmentBuilder` Frontend‑Type — heute kein Renderer. Im Zuge des Cleanups Alias auf `JsonEditor` (oder echten Builder, falls Pilot es noch in dieser Iteration braucht).
+
+## Ziel und Nicht-Ziele
+
+**Ziele:**
+- Generische, deterministische Handover‑Logik zwischen allen Nodes basierend auf typisierten DataRefs.
+- Reichhaltige rekursive Output‑Schemas mit `itemSchema` für Listen und Provenienz‑Feldern (SharePoint‑Source, ConnectionRef) wo der Konsumer sie picken können soll.
+- DataPicker mit lexikalischem Loop‑Scoping, Type‑Compat‑Anzeige (grün/gelb/rot), rekursiver Schema‑Navigation.
+- Hard Validation: kein Run bei fehlenden Bindings oder Type‑Mismatch.
+- Auto‑Suggest beim Wire‑Connect (UX‑Komfort, nicht Runtime‑Magie) für deterministische Defaults nach Name+Type‑Match.
+- AI‑Tool‑Surface: Endpoint, der für eine Node die strukturierte Liste aller pickbaren Upstream‑Pfade liefert.
+- Migration aller existierenden Workflows in DB `poweron_graphicaleditor` ohne manuelle Nacharbeit.
+- `input.form` als graph‑defined‑Schema sauber unterstützt; Picker downstream zeigt User‑definierte Felder mit korrekten Typen.
+
+**Explizit NICHT:**
+- Keine Runtime‑dynamischen Schemas. `ai.extractStructured` wird **nicht** eingeführt; `data.transform` wird **entfernt**.
+- Kein Self‑Service Node‑Type‑Generator (User‑editierbare Node‑Typen) in dieser Iteration.
+- Keine semantische Type‑Refinement (Subtype‑Polymorphie über strukturelles Matching hinaus). Bleibt auf strukturellem Match.
+- Keine Backwards‑Compat: alte Workflows werden migriert, der `_wireHandover`‑Code wird gelöscht, kein Fallback.
+- Keine Änderung am Scheduler / Pause‑Resume‑Datenmodell jenseits Validation‑Hook.
+- Keine Änderung an Action‑Library (`workflows/methods/`) — Adapter dort bekommen nur erweiterte Outputs, keine neue Aufrufkonvention.
+
+## Betroffene Module
+
+**Gateway (`gateway/modules/`):**
+- `features/graphicalEditor/portTypes.py` — `PortField` erweitern (`itemSchema`, `fields`, `enumValues`); `PORT_TYPE_CATALOG` erweitern um `Document`, `FileItem`, `EmailItem`, `TaskItem`, `ConnectionRef`, `SharePointFolderRef`, `SharePointFileRef`; `INPUT_EXTRACTORS` **entfernen**.
+- `features/graphicalEditor/nodeDefinitions/*.py` — alle Outputs anreichern um Provenienz (`source`, `connection`) wo sinnvoll; `outputPorts.dynamic`/`deriveFrom` Marker auf `input.form` beschränken und in `{kind: "fromGraph", parameter: "fields"}`‑Form normalisieren.
+- `features/graphicalEditor/nodeRegistry.py` + `routeFeatureGraphicalEditor.py` — neue Endpoints: `GET /{instanceId}/upstream-paths/{nodeId}`, `POST /{instanceId}/validate-graph`.
+- `workflows/automation2/executors/actionNodeExecutor.py` — `_wireHandover` **entfernen**; `_resolveConnectionParam` bleibt für resolver, wird aber nur noch nach Parameter‑Resolution gerufen.
+- `workflows/automation2/executors/dataExecutor.py` — `data.transform` **entfernen**, `data.aggregate` und `data.filter` mit reichhaltigen Output‑Schemas.
+- `workflows/automation2/executionEngine.py` — Validation‑Hook vor Run‑Start; Loop‑Body‑Scope an `executeGraph` propagieren.
+- `workflows/automation2/graphUtils.py` — `validateGraph`: hart blockierend; `resolveParameterReferences`: graph‑defined‑Schema‑Pfad ergänzen.
+- `workflows/methods/sharepoint/`, `methods/outlook/`, `methods/clickup/`, `methods/trustee/`, `methods/file/` — Adapter‑Outputs anreichern (Connection‑Ref, Source‑Pfad).
+- Migrations‑Skript `scripts/migration/2026-04-pick-not-push-migration.py` (neu) — scannt `AutoWorkflow.graph`, ergänzt explizite DataRefs anstelle implizitem Wire‑Handover.
+- Test‑Pakete:
+ - `gateway/tests/unit/graphicalEditor/test_port_schema_recursive.py`
+ - `gateway/tests/unit/graphicalEditor/test_validate_typed_hard.py`
+ - `gateway/tests/integration/graphicalEditor/test_upstream_paths_api.py`
+ - `gateway/tests/integration/graphicalEditor/test_pwg_pilot_typed.py`
+ - `gateway/tests/unit/migration/test_pick_not_push_migration.py`
+ - pro Adapter (sharepoint/outlook/clickup/trustee/file): Schema‑Compliance‑Test
+
+**Frontend (`frontend_nyla/src/`):**
+- `api/workflowApi.ts` — Interfaces: `PortSchema` rekursiv (`fields`, `itemSchema`); `DataRef.expectedType`; `NodeType.outputPorts.schema` darf `string | {kind:"fromGraph", parameter:string}` sein.
+- `components/FlowEditor/nodes/shared/dataRef.ts` — `DataRef` um `expectedType` erweitern; Helper `isCompatible(produced, accepted)`.
+- `components/FlowEditor/nodes/shared/DataPicker.tsx` — Scope: BFS rückwärts via Connections + transitive Loop‑Body‑Hierarchie; rekursive Schema‑Navigation (verschachtelte fields, list `itemSchema` unwrap); `loop.item`/`loop.index`/`loop.total` pro umgebendem Loop; Type‑Compat‑Pills.
+- `components/FlowEditor/nodes/shared/scopeHelpers.ts` (neu) — `computePickableScope(nodeId, graph, nodeTypes)`, `unwrapListItemSchema()`, `resolveTransitChain()`.
+- `components/FlowEditor/context/Automation2DataFlowContext.tsx` — `parseGraphDefinedSchema(node, paramKey)` für `input.form`; cached pro Node.
+- `components/FlowEditor/editor/NodeConfigPanel.tsx` — DataRef‑Pills mit Type‑Status; fehlt Required‑Binding → Visualisierung; nicht‑bindbare Connection‑Pickers (wenn upstream `ConnectionRef` verfügbar) als Hybrid‑Picker (Static‑User‑Connection ODER DataRef).
+- `components/FlowEditor/nodes/frontendTypeRenderers/index.tsx` — `attachmentBuilder` als Alias auf `JsonEditor` (übergangsweise); `ConnectionPicker` 3‑Modus (Link bei 0 Connections, Auto‑Display bei 1, Dropdown bei ≥2) — aus dem überholten Vorgänger‑Plan übernommen.
+- `components/FlowEditor/editor/FlowCanvas.tsx` — Auto‑Suggest Modal beim Wire‑Connect; Wire‑Farbe nach Type‑Compat (grün/gelb/rot); Validation‑Indicator pro Node.
+- `components/FlowEditor/editor/Automation2FlowEditor.tsx` — Run‑Button disabled bei Validation‑Fehler; Validation‑Panel sichtbar mit Klick‑Zu‑Node‑Navigation.
+
+**DB‑Migration:** Nein im Schema‑Sinn (kein `AutoWorkflow`‑Table‑Change). **Daten‑Migration ja:** `AutoWorkflow.graph`‑JSON wird einmalig durch Migrations‑Skript transformiert.
+
+**Andere Komponenten:**
+- AI Agent (`gateway/modules/serviceCenter/services/serviceAgent/`): `workflowTools` Tool‑Schemas erweitern, sodass `bindNodeParameter`‑Tool die KI zur expliziten DataRef‑Erzeugung führt; Prompts für Workflow‑Generation aktualisieren.
+
+## Entscheidungen
+
+| Datum | Entscheidung | Begründung |
+|-------|-------------|------------|
+| 2026‑04‑23 | Pick‑not‑Push als Grundprinzip — `INPUT_EXTRACTORS` und `_wireHandover` entfernen | Heuristisches Push erzeugt nicht‑deterministisches, AI‑undurchsichtiges Verhalten |
+| 2026‑04‑23 | Static‑Only Schemas: Code‑Katalog ODER graph‑defined (nur `input.form`) | Keine Runtime‑Schema‑Unsicherheit; deterministische Picker‑/AI‑Sicht |
+| 2026‑04‑23 | Kein `ai.extractStructured` | AI kann Schema‑Compliance nicht garantieren; UDM (`trustee.extractFromFiles`) + `trustee.queryData` decken strukturierte Extraktion ab |
+| 2026‑04‑23 | `data.transform` ersatzlos entfernen | Funktional redundant zu DataRefs am Konsumer |
+| 2026‑04‑23 | Connection als Hybrid: Source‑Picker + ConnectionRef‑Output + Downstream‑DataRef | Konsistente Picker‑UX, keine Secrets in Datenflüssen |
+| 2026‑04‑23 | Loop‑Scoping lexikalisch + `loop.item`/`loop.index` zusätzlich | Einfacher als Magic‑Envelope, native an Datenfluss‑Topologie |
+| 2026‑04‑23 | Hard Validation (Mismatch blockt Run) | Keine späten Runtime‑Überraschungen, klare Fehler |
+| 2026‑04‑23 | Greenfield + Migrations‑Skript, kein Fallback | Eine Wahrheit, Code‑Pfade einfach |
+| 2026‑04‑23 | `attachmentBuilder` als Alias auf `JsonEditor` (übergangsweise) | Pilot benötigt funktionierenden Renderer; richtiger Builder später |
+| 2026‑04‑23 | `ConnectionPicker` 3‑Modus (Link/Auto/Dropdown) bei Source‑Nodes | UX aus überholtem Plan übernommen, da pragmatisch |
+
+## Umsetzungs-Checkliste
+
+### Phase 0 — Plan‑Hygiene & Audit (markdown only)
+- [ ] Vorgänger‑Plan `wiki/c-work/1-plan/2026-04-graph-editor-node-config-fixes.md` als obsolet markieren (``) und mit Forward‑Link auf diesen Plan versehen, dann nach `wiki/z-archive/` verschieben.
+- [ ] Anhang A „Schema‑Audit" am Ende dieses Plans pflegen (siehe unten): pro existierender Node Soll‑Schema (rekursiv, mit Provenienz wo relevant).
+
+### Phase 1 — Schema‑Erweiterung (Backend)
+- [ ] `portTypes.py`: `PortField` erweitern um optional `fields: List[PortField]` (verschachtelt) und `itemSchema: PortField` (für Listen) und `enumValues: List[str]`.
+- [ ] `PORT_TYPE_CATALOG`: neue Entries `Document`, `FileItem`, `EmailItem`, `TaskItem`, `ConnectionRef { id, authority, label }`, `SharePointFolderRef { siteUrl, driveId, folderPath, label }`, `SharePointFileRef { …, fileName }`, `UdmPage`, `UdmBlock` (rekursive UDM‑Strukturen).
+- [ ] `DocumentList`, `FileList`, `EmailList`, `TaskList`: jeweils `itemSchema` referenziert auf den passenden Item‑Typ.
+- [ ] Pro Producer‑Output: Provenienz ergänzen (`source: SharePointFolderRef`, `connection: ConnectionRef` für `sharepoint.*`; analog für `email.*`, `clickup.*`, `trustee.*`).
+- [ ] `_normalizeToSchema` strict modus: fehlende required Felder → `RuntimeError` mit klarem Schema‑Compliance‑Hinweis.
+- [ ] `INPUT_EXTRACTORS` aus `portTypes.py` **entfernen** (alle Funktionen + Dict).
+
+### Phase 2 — Adapter‑Anpassung (Backend, Action Library)
+- [ ] `methods/sharepoint/` Aktionen `findDocumentPath`, `readDocuments`, `listDocuments`, `downloadFileByPath`, `uploadFile`, `copyFile`: Output‑Builder erweitern um `source`, `connection`.
+- [ ] `methods/outlook/` analog: `connection` in jedem Output.
+- [ ] `methods/clickup/` analog.
+- [ ] `methods/trustee/` (`extractFromFiles`, `processDocuments`): UDM‑Output sauber rekursiv typisieren.
+- [ ] `methods/file/create`: Output‑Schema auf `Document` mappen.
+- [ ] Pro Adapter ein Compliance‑Test (`gateway/tests/integration/methods/test__schema_compliance.py`): mock + reale Mini‑Outputs gegen Soll‑Schema validiert.
+
+### Phase 3 — Loop‑Scoping & DataPicker (Frontend)
+- [ ] `nodes/shared/scopeHelpers.ts` (neu): `computePickableScope(nodeId, graph, nodeTypes)` — BFS rückwärts via `connections` + transitive Loop‑Body‑Hierarchie; `unwrapListItemSchema(producerSchema, fieldPath)` für Loop‑Item‑Typ; `resolveTransitChain(nodeId, graph, nodeTypes)` für Transit‑Auflösung.
+- [ ] `DataPicker.tsx`:
+ - rekursive Schema‑Navigation (verschachtelte `fields`, list `itemSchema` automatisch entpackt unter Loop‑Body).
+ - pro umgebendem Loop zusätzlich Sektion „Loop ($loopNodeLabel)" mit `loop.item`, `loop.index`, `loop.total`.
+ - Type‑Pills pro Pick: grün (identisch/kompatibel), gelb (saubere Coercion), rot (Mismatch).
+ - System‑Sektion bleibt.
+- [ ] `dataRef.ts`: `DataRef` um `expectedType: string` erweitern; Helper `isCompatible(produced, accepted): "ok" | "coerce" | "mismatch"`.
+- [ ] Frontend‑Unit‑Tests für `scopeHelpers` und Picker‑Renderlogik.
+
+### Phase 4 — Pick‑not‑Push: Executor‑Cleanup (Backend)
+- [ ] `actionNodeExecutor.py`: `_wireHandover` und alle Aufrufer **entfernen**.
+- [ ] `resolveParameterReferences` in `graphUtils.py`: nur noch `DataRef` / `SystemVar` / `Static` / graph‑defined; Helper `parseGraphDefinedSchema(node, paramKey) -> PortSchema`.
+- [ ] `validateGraph` in `graphUtils.py`: hart blockierend bei (a) fehlender Required‑Bindung, (b) Type‑Mismatch (mit `isCompatible`‑Logik vom Frontend angeglichen — gemeinsame TypeScript/Python Spec dokumentiert).
+- [ ] `executionEngine.executeGraph`: vor Schleifenstart `validateGraph`‑Aufruf; bei Fehler `RunValidationError` mit Liste pro betroffenem Node/Param.
+- [ ] `_resolveConnectionParam` bleibt, wird nach `resolveParameterReferences` gerufen (DataRef → ConnectionRef‑Dict → resolver liest `id`).
+
+### Phase 5 — Auto‑Suggest UX beim Wire (Frontend)
+- [ ] `FlowCanvas.tsx`: bei Wire‑Connect (`onConnectionsChange`) die downstream‑Node‑Inputs gegen den neuen upstream‑Output prüfen.
+- [ ] Vorschlags‑Logik: Match nach (a) Parameter‑Name = Schema‑Field‑Name + Type‑Compat ok, (b) Type‑Compat ok mit eindeutigem Field. → DataRef‑Vorschläge.
+- [ ] Modal/Popover „Vorgeschlagene Bindings übernehmen?" mit Apply‑All / Per‑Item‑Akzept.
+- [ ] Bei genau einer eindeutigen Bindung pro Param: Direkt vorausgefüllt mit Undo‑Toast.
+- [ ] Connection‑Picker in Downstream‑Nodes wird zum **Hybrid‑Picker**: zeigt Static‑User‑Connection (Picker) ODER DataRef (auf `ConnectionRef`); bei aktivem upstream‑`ConnectionRef` wird DataRef vorgeschlagen.
+
+### Phase 6 — `ConnectionPicker` 3‑Modus + Renderer‑Audit (Frontend)
+- [ ] `frontendTypeRenderers/index.tsx` `ConnectionPicker`: 3 Modi je nach Anzahl verfügbarer Connections für Authority — 0: Link auf User‑Connections‑Seite, 1: Auto‑Display ohne Dropdown, ≥2: Dropdown.
+- [ ] `attachmentBuilder` Alias auf `JsonEditor` einführen + Console‑Warnung im Fallthrough für unbekannte FrontendTypes.
+- [ ] FrontendType‑Audit gegen alle `nodeDefinitions/*.py`: jede dort verwendete `frontendType` muss in `FRONTEND_TYPE_RENDERERS` einen Renderer haben (oder klar kommentiert TODO).
+
+### Phase 7 — AI Tool Surface (Backend + Agent)
+- [ ] `routeFeatureGraphicalEditor.py`: `GET /{instanceId}/upstream-paths/{nodeId}` → Liste `{producerNodeId, producerLabel, path, type, label, scopeOrigin: "data"|"loop"|"system"}`.
+- [ ] `nodeRegistry.py`: Response `nodeTypes` liefert vollständig rekursive `inputPorts.accepts` und `outputPorts.schema` (verschachtelt).
+- [ ] `serviceCenter/services/serviceAgent/workflowTools.py`: neues Tool `bindNodeParameter(workflowId, nodeId, paramName, dataRef|staticValue|systemVar)` mit Server‑seitiger Validation gegen Type‑Compat.
+- [ ] Prompt‑Update für Workflow‑Generation: KI generiert immer explizite DataRefs; nutzt `upstream-paths` zur Discovery.
+
+### Phase 8 — `input.form` als graph‑defined Schema
+- [ ] `nodeDefinitions/input.py` `input.form.outputPorts`: ersetze `{schema: "FormPayload", dynamic: True, deriveFrom: "fields"}` durch `{schema: {kind: "fromGraph", parameter: "fields"}}`.
+- [ ] `parseGraphDefinedSchema(node, "fields")` in `graphUtils.py` (Backend) und Spiegel in `Automation2DataFlowContext.tsx` (Frontend) — gemeinsame Spec, getrennte Implementierung.
+- [ ] FieldBuilder im Frontend (`fieldBuilder` Renderer): erlaubt verschachtelte fields (object), Typed Items für Listen, Type‑Picker (`str/number/bool/date/datetime/object/list`).
+- [ ] Picker downstream zeigt `formNode.payload.` mit korrektem Type.
+
+### Phase 9 — Migration bestehender Workflows
+- [ ] `scripts/migration/2026-04-pick-not-push-migration.py`:
+ - lädt alle `AutoWorkflow.graph` aus `poweron_graphicaleditor`;
+ - simuliert die alte `_wireHandover`‑Logik deterministisch;
+ - schreibt explizite DataRefs in den Graph;
+ - Trockenlauf‑Modus mit Diff‑Output;
+ - Live‑Modus mit Backup‑Snapshot der DB vor Schreiben.
+- [ ] Unit‑Tests für die Migrations‑Funktion mit Beispiel‑Graphen (inkl. PWG‑Pilot).
+- [ ] Integration‑Test: PWG‑Pilot Workflow läuft nach Migration ohne erneutes Connection‑Prompting; n4/n10 nutzen DataRef auf n2.connection.
+- [ ] `data.transform` Nodes in alten Workflows: Migrations‑Skript gibt Warnung pro Vorkommen aus (manuell zu refactoren — kein Auto‑Cleanup, weil semantisch).
+
+### Phase 10 — Dokumentation & Abschluss
+- [ ] `wiki/b-reference/gateway/automation.md`: Abschnitt „Pick‑not‑Push Handover" + Removed `INPUT_EXTRACTORS`.
+- [ ] `wiki/b-reference/gateway/workflow.md`: Abschnitt UDM/Loop/KI‑Badge ergänzen um neue Schema‑Tiefe und Loop‑Scoping.
+- [ ] `wiki/b-reference/frontend-nyla/architecture.md`: Abschnitt FlowEditor mit Type‑Compat, Auto‑Suggest, Hybrid‑Connection‑Picker.
+- [ ] `wiki/TOPICS.md`: Eintrag „Typed Generic Handover (build/done)" verlinken.
+- [ ] Plan‑Doc Status updaten und nach `c-work/2-build/` → `c-work/3-validate/` → `c-work/4-done/` durchschieben.
+
+## Akzeptanzkriterien
+
+| # | Kriterium (Given‑When‑Then) | Prio |
+|---|---------------------------|------|
+| 1 | Given PWG‑Pilot Workflow nach Migration, When ausgeführt, Then `n4 sharepoint.downloadFile` und `n10 email.draftEmail` erhalten ihre msft‑Connection per DataRef auf `n2.connection` ohne erneutes User‑Prompt; Run läuft erfolgreich durch | must |
+| 2 | Given Workflow mit Type‑Mismatch (z.B. `DocumentList` → `int` Param), When `validateGraph` aufgerufen, Then Validation‑Error mit Path/Param‑Liste; When `executeGraph` aufgerufen, Then sofortiger `RunValidationError` ohne Adapter‑Aufruf | must |
+| 3 | Given Workflow mit `flow.foreach` über `nodeX.documents`, When im Body‑Node DataPicker geöffnet, Then Sektion „Loop (foreachLabel)" zeigt `loop.item: Document`, `loop.index: int`, `loop.total: int`; outer scope inkl. `nodeX.connection`, `nodeX.source` weiterhin pickbar | must |
+| 4 | Given `input.form` mit User‑definierten Feldern `{mieter: str, betrag: number}`, When downstream DataPicker geöffnet, Then `formNode.payload.mieter` (str) und `formNode.payload.betrag` (number) sind separat pickbar mit korrekten Typ‑Pills | must |
+| 5 | Given AI Agent generiert neuen Workflow, When `GET /{instanceId}/upstream-paths/{nodeId}` aufgerufen, Then strukturierte Pfad‑Liste mit `producerNodeId`, `path`, `type`, `label`, `scopeOrigin` zurück; KI generiert valide DataRefs ohne leere `connectionReference`‑Felder | must |
+| 6 | Given Migrations‑Skript Trockenlauf auf bestehenden Workflows, When ausgeführt, Then für jede Node mit implizitem Wire‑Handover wird ein expliziter DataRef‑Vorschlag im Diff angezeigt; When Live‑Lauf, Then alle Workflows passieren `validateGraph` ohne Fehler | must |
+| 7 | Given DataPicker‑Bindung mit perfekt passendem Typ, When User pickt, Then grünes Pill; bei sauberer Coercion (`int → str`) gelb mit Hinweis; bei Mismatch (`DocumentList → int`) rot und Save‑Button blockiert | should |
+| 8 | Given Wire zwischen zwei Nodes neu gezogen, When Auto‑Suggest aktiv, Then Modal listet alle nach Name+Type matchenden Bindings; bei eindeutigem Match wird vorausgefüllt mit Undo‑Toast | should |
+| 9 | Given `ConnectionPicker` für Authority `msft` und User hat 0 Connections, Then Link „Connection erstellen" statt Dropdown; bei 1 Connection Auto‑Display; bei ≥2 Dropdown | should |
+| 10 | Given Source‑Adapter `methods/sharepoint/listDocuments`, When ausgeführt, Then Output enthält `connection: ConnectionRef`, `source: SharePointFolderRef`, `documents: List[Document]` mit voll typisierten Document‑Items | must |
+| 11 | Given `data.transform` Node in altem Workflow, When Migrations‑Skript läuft, Then Warning im Diff (kein Auto‑Removal); After Cleanup‑Pass: `data.transform` aus `nodeRegistry` entfernt | should |
+
+## Testplan
+
+| ID | AC | Art | Automatisiert | Repo‑Pfad | Status |
+|----|----|-----|--------------|-----------|--------|
+| T1 | 1 | integration | ja | `gateway/tests/integration/graphicalEditor/test_pwg_pilot_typed.py` | pending |
+| T2 | 2 | unit | ja | `gateway/tests/unit/graphicalEditor/test_validate_typed_hard.py` | pending |
+| T3 | 3 | frontend unit | ja | `frontend_nyla/src/components/FlowEditor/__tests__/dataPicker.scope.test.ts` | pending |
+| T4 | 4 | frontend unit + backend unit | ja | `frontend_nyla/.../__tests__/dataPicker.formSchema.test.ts` + `gateway/tests/unit/graphicalEditor/test_parse_graph_defined_schema.py` | pending |
+| T5 | 5 | api | ja | `gateway/tests/integration/graphicalEditor/test_upstream_paths_api.py` | pending |
+| T6 | 6 | migration | ja | `gateway/tests/unit/migration/test_pick_not_push_migration.py` | pending |
+| T7 | 7 | frontend unit | ja | `frontend_nyla/.../__tests__/dataPicker.typeCompat.test.ts` | pending |
+| T8 | 8 | frontend e2e | ja (Playwright opt) | `frontend_nyla/tests/e2e/wireAutoSuggest.spec.ts` | pending |
+| T9 | 9 | frontend unit | ja | `frontend_nyla/.../__tests__/connectionPicker.modes.test.ts` | pending |
+| T10 | 10 | api/integration | ja | `gateway/tests/integration/methods/test_sharepoint_schema_compliance.py` (+ `_outlook`, `_clickup`, `_trustee`, `_file`) | pending |
+| T11 | 11 | unit | ja | `gateway/tests/unit/migration/test_data_transform_warning.py` | pending |
+
+## Links
+
+- Vorgänger (done): `wiki/c-work/4-done/2026-04-generic-graph-editor.md`
+- Vorgänger (obsolet, in Phase 0 zu archivieren): `wiki/c-work/1-plan/2026-04-graph-editor-node-config-fixes.md`
+- Pilot‑Bezug: `wiki/c-work/4-done/2026-04-pwg-pilot-mietzinsbestaetigung-workflow.md`
+- Beispiel‑Workflow für Smoke‑Test: `local/temp/pwg-pilot-jahresmietzinsbestätigung.workflow (1).json`
+- PR: TBD
+- Issue: TBD
+
+## Abschluss
+
+- [ ] `wiki/b-reference/gateway/automation.md` aktualisiert (Pick‑not‑Push, Removed Heuristik)
+- [ ] `wiki/b-reference/gateway/workflow.md` aktualisiert (Schema‑Tiefe, Loop‑Scoping)
+- [ ] `wiki/b-reference/frontend-nyla/architecture.md` aktualisiert (FlowEditor‑Erweiterungen)
+- [ ] `wiki/TOPICS.md` aktualisiert (neuer Eintrag „Typed Generic Handover")
+- [ ] Dieses Dokument → `wiki/z-archive/` verschoben
+
+---
+
+## Anhang A — Schema‑Audit (Soll‑Stand pro Node‑Output)
+
+> Wird in Phase 0 vollständig befüllt; hier die Zielform und der Anfang der Inhalte. Stand `PORT_TYPE_CATALOG` heute siehe `gateway/modules/features/graphicalEditor/portTypes.py:59–170`.
+
+### Neue / erweiterte Item‑Schemas im Katalog
+
+| Schema | Felder (Kurzform) | Anmerkung |
+|--------|-------------------|-----------|
+| `Document` | `id, name, mimeType, sizeBytes, downloadUrl, source: SharePointFileRef?` | Item für `DocumentList`; Provenienz optional je nach Producer |
+| `FileItem` | `id, name, path, mimeType, sizeBytes, modifiedAt` | Item für `FileList` |
+| `EmailItem` | `id, subject, from, to, receivedAt, hasAttachments, bodyPreview` | Item für `EmailList` |
+| `TaskItem` | `id, title, status, assignee, dueDate, listId` | Item für `TaskList` |
+| `ConnectionRef` | `id, authority, label` | **keine Secrets** — nur Identifikator |
+| `SharePointFolderRef` | `siteUrl, driveId, folderPath, label` | Provenienz für SharePoint‑Listings |
+| `SharePointFileRef` | `siteUrl, driveId, filePath, fileName, label` | Provenienz für einzelne SharePoint‑Files |
+| `UdmPage` | `pageNumber, blocks: List[UdmBlock]` | UDM‑Seite |
+| `UdmBlock` | `kind, text, children?: List[UdmBlock]` | UDM‑Block (rekursiv) |
+
+### Anreicherung bestehender Output‑Schemas
+
+| Schema | Heute | Soll |
+|--------|-------|------|
+| `DocumentList` | `documents: List[Document]` | `+ source: SharePointFolderRef? + connection: ConnectionRef? + count: int` |
+| `FileList` | `files: List[File]` | `+ source: SharePointFolderRef? + connection: ConnectionRef? + count: int`; `itemSchema` = `FileItem` |
+| `EmailList` | `emails: List[Email]` | `+ connection: ConnectionRef? + count: int`; `itemSchema` = `EmailItem` |
+| `TaskList` | `tasks: List[Task]` | `+ connection: ConnectionRef? + listId? + count: int`; `itemSchema` = `TaskItem` |
+| `EmailDraft` | `subject, body, to, cc?, attachments?` | `+ connection: ConnectionRef?` |
+| `AiResult` | flat | bleibt, `responseData` weiterhin `Dict` (nicht typisiert — bewusst, weil AI‑Antwort) |
+| `UdmDocument` | `id, sourceType, sourcePath, children: List[Any]` | `children: List[UdmPage]` (rekursiv typisiert) |
+| `ActionResult` | `success, error?, data?` | bleibt; `data` ist `Dict` (catch‑all für nicht‑typisierte Adapter) |
+| `Transit` | leer | bleibt — Picker folgt Transit‑Chain |
+
+### Pro Node‑Definition (Auszug — vollständig in Phase 0)
+
+| Node | Output heute | Output Soll |
+|------|--------------|-------------|
+| `sharepoint.findFile` | `FileList` | `FileList` mit `source`, `connection` befüllt |
+| `sharepoint.listFiles` | `FileList` | `FileList` mit `source`, `connection` befüllt |
+| `sharepoint.downloadFile` | `DocumentList` | `DocumentList` mit `source`, `connection` befüllt |
+| `sharepoint.readFile` | `DocumentList` | `DocumentList` mit `source`, `connection` befüllt |
+| `email.draftEmail` | `EmailDraft` | `EmailDraft` mit `connection` befüllt |
+| `email.checkEmail` | `EmailList` | `EmailList` mit `connection` befüllt |
+| `clickup.searchTasks` | `TaskList` | `TaskList` mit `connection`, `listId` befüllt |
+| `trustee.extractFromFiles` | `UdmDocument` | `UdmDocument` mit voll typisierten `children: List[UdmPage]` |
+| `trustee.queryData` | `Dict` (heute) | typisiertes `QueryResult { rows: List[Dict], schema: List[ColumnSchema] }` (neuer Eintrag im Katalog) |
+| `input.form` | `FormPayload` (`dynamic`) | `{kind:"fromGraph", parameter:"fields"}` — graph‑defined |
+| `data.transform` | (vorhanden) | **entfernt** |
+| `data.aggregate` | `AggregateResult` | bleibt, `items: List[Any]` (generisch über Loop‑Item‑Typ) |
+| `data.consolidate` / `ai.consolidate` | `ConsolidateResult` | bleibt |
+
diff --git a/c-work/4-done/2026-04-graph-editor-node-config-fixes.md b/c-work/4-done/2026-04-graph-editor-node-config-fixes.md
new file mode 100644
index 0000000..21c31b0
--- /dev/null
+++ b/c-work/4-done/2026-04-graph-editor-node-config-fixes.md
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+> **Obsolet — ersetzt durch [`c-work/1-plan/2026-04-typed-generic-handover.md`](../1-plan/2026-04-typed-generic-handover.md).**
+>
+> Dieser Plan behandelte die Symptome (Connection-Inheritance-Service, Wire-Source-Badge, attachmentBuilder-Alias) als Workarounds um den heuristischen `_wireHandover` herum. Die Diskussion vom 2026‑04‑23 hat ergeben, dass das Modell selbst nicht trägt: der „Push"-Handover via `INPUT_EXTRACTORS` ist generisch nicht beherrschbar. Der Nachfolge-Plan ersetzt das durch ein **Pick-not-Push** Modell mit reichhaltigen statischen Schemas, harter Type-Validierung und expliziten DataRefs als einzigem Bindungs-Mechanismus. Drei Punkte aus diesem Plan (3-Modus `ConnectionPicker`, `attachmentBuilder` Renderer-Alias, FrontendType-Audit) wurden in den Nachfolger als Phase 6 übernommen.
+
+# Graph-Editor: Connection-UX, Wire-Handover und Feld-Rendering bereinigen (obsolet)
+
+## Beschreibung und Kontext
+
+Der Graphical Editor (`graphicalEditor`-Feature) ist seit dem Generic-Graph-Editor-Refactor (`c-work/4-done/2026-04-generic-graph-editor.md`) auf typisierte Ports + Wire-Handover umgestellt. Beim Pilot-Workflow PWG Mietzinsbestaetigung (`local/temp/pwg-pilot-jahresmietzinsbestätigung.workflow (1).json`) zeigen sich vier konkrete Schwachstellen, die das User-Erlebnis im Editor brechen:
+
+1. **Connection wird pro Node neu erfragt.** Im PWG-Workflow ist `n2.sharepoint.listFiles` mit `connection:msft:p.motsch@valueon.ch` konfiguriert. `n4.sharepoint.downloadFile` und `n10.email.draftEmail` haben dieselbe Authority (`msft`), aber `connectionReference: ""`. Der `_wireHandover` in `gateway/modules/workflows/automation2/executors/actionNodeExecutor.py` propagiert nur Port-Schema-Felder (`documents`, `emails`, ...) via `INPUT_EXTRACTORS` (`gateway/modules/features/graphicalEditor/portTypes.py`). `connectionReference` wird nirgends weitergereicht. Folge: jede Node fragt erneut nach Connection.
+2. **`ConnectionPicker` immer als Dropdown.** `frontend_nyla/src/components/FlowEditor/nodes/frontendTypeRenderers/index.tsx` (`ConnectionPicker`, Z. 153–198) rendert immer `