Full graph-based workflow execution engine with: - WorkflowGraphRuntime with two-phase dispatch (collect → fire Celery tasks) - Node registry with contract validation, socket types, execution kinds - WorkflowRuntimeServices: preflight, context resolution, shadow-mode A/B - WorkflowRouter: CRUD + dispatch/preflight/run-history API endpoints - OutputTypeContracts: workflow binding, rollout-mode resolution - Admin router: output-type workflow binding endpoints - Frontend: complete workflow editor with drag-drop canvas, node inspector, module bundles, reference bundles, preflight panel, validation banner, authoring guidance, blueprint templates, shadow/rollout gate UI - Tests: comprehensive coverage for all workflow modules - Docs: NODE_CONTRACT_AUDIT and VALIDATION_ERROR_INVENTORY All 20 blocks from NEXT_20_BLOCK_BATCH_PLAN completed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
245 lines
9.4 KiB
Markdown
245 lines
9.4 KiB
Markdown
# Workflow Node Contract Audit
|
|
|
|
Stand: April 12, 2026
|
|
|
|
## Scope
|
|
|
|
Geprüft wurden:
|
|
|
|
- [`backend/app/domains/rendering/workflow_node_registry.py`](/home/hartmut/Documents/Copilot/schaefflerautomat/backend/app/domains/rendering/workflow_node_registry.py)
|
|
- [`backend/app/domains/rendering/workflow_schema.py`](/home/hartmut/Documents/Copilot/schaefflerautomat/backend/app/domains/rendering/workflow_schema.py)
|
|
- [`backend/app/domains/rendering/workflow_graph_runtime.py`](/home/hartmut/Documents/Copilot/schaefflerautomat/backend/app/domains/rendering/workflow_graph_runtime.py)
|
|
- [`frontend/src/components/workflows/workflowNodeContracts.ts`](/home/hartmut/Documents/Copilot/schaefflerautomat/frontend/src/components/workflows/workflowNodeContracts.ts)
|
|
- [`frontend/src/components/workflows/WorkflowNodeInspector.tsx`](/home/hartmut/Documents/Copilot/schaefflerautomat/frontend/src/components/workflows/WorkflowNodeInspector.tsx)
|
|
- [`frontend/src/components/workflows/workflowGraphDraft.ts`](/home/hartmut/Documents/Copilot/schaefflerautomat/frontend/src/components/workflows/workflowGraphDraft.ts)
|
|
|
|
## Findings
|
|
|
|
### 1. Root-context inputs were modeled like normal upstream sockets
|
|
|
|
Betroffen:
|
|
|
|
- `resolve_step_path` mit `cad_file_record`
|
|
- `order_line_setup` mit `order_line_record`
|
|
|
|
Root cause:
|
|
|
|
- Das Backend seedingt diese Eingänge implizit aus dem Workflow-Kontext.
|
|
- Der Editor behandelte sie trotzdem als normale Canvas-Ports.
|
|
|
|
Folge:
|
|
|
|
- Entry-Nodes sahen aus, als müssten sie zusätzlich verkabelt werden.
|
|
- Das erzeugte genau die Art von unklaren Input-Anforderungen, die im aktuellen Workflow-Editor stören.
|
|
|
|
Maßnahme:
|
|
|
|
- Root-context inputs werden im Frontend separat als Kontextanforderung modelliert.
|
|
- Sie werden nicht mehr als normale verkabelbare Upstream-Sockets dargestellt.
|
|
|
|
### 2. Node authoring semantics were implicit instead of explicit
|
|
|
|
Root cause:
|
|
|
|
- Der Editor wusste bislang zwar, welche Felder und Ports existieren, aber nicht, welches Authoring-Muster eine Node eigentlich hat.
|
|
|
|
Folge:
|
|
|
|
- `0 inspector vars` oder `1 input socket` war im UI technisch korrekt, aber semantisch oft unverständlich.
|
|
|
|
Maßnahme:
|
|
|
|
- Nodes werden jetzt explizit als `Context Entry`, `Connection-Driven`, `Inspector-Driven` oder `Hybrid` beschrieben.
|
|
|
|
### 3. Registry coverage is broad, but some nodes are intentionally connection-only
|
|
|
|
Nodes mit `0` Inspector-Feldern:
|
|
|
|
- `resolve_step_path`
|
|
- `occ_object_extract`
|
|
- `occ_glb_export`
|
|
- `thumbnail_save`
|
|
- `order_line_setup`
|
|
- `stl_cache_generate`
|
|
|
|
Bewertung:
|
|
|
|
- Das ist nicht automatisch ein Defekt.
|
|
- Diese Nodes brauchen vor allem klare Authoring-Erklärung und keine künstlichen Dummy-Einstellungen.
|
|
|
|
### 4. Render/runtime parameter alignment is already strong for core render nodes
|
|
|
|
Der bestehende Testpfad deckt insbesondere für `blender_still` und `blender_turntable` bereits ab, dass deklarierte Felder von der Runtime unterstützt werden.
|
|
|
|
Nächste Lücke:
|
|
|
|
- systematische Prüfung der restlichen Bridge-/Output-Nodes gegen Runtime-Parameter und Template-Inputs
|
|
|
|
## Current Batch Outcome
|
|
|
|
Batch A konzentriert sich zuerst auf:
|
|
|
|
1. sichtbaren 20-Block-Plan
|
|
2. Audit-Dokumentation
|
|
3. saubere Trennung von Root-Kontext und Upstream-Wiring
|
|
4. explizite Authoring-Semantik im Editor
|
|
|
|
## Block 5 Inventory: Implicit Requirement Nodes
|
|
|
|
### A. Korrekt feldlose Nodes, die nur bessere Authoring-Semantik brauchten
|
|
|
|
- `resolve_step_path`
|
|
- echter `Context Entry`
|
|
- braucht nur `cad_file_record` aus dem Workflow-Kontext
|
|
- keine zusätzlichen Inspector-Variablen sinnvoll
|
|
- `order_line_setup`
|
|
- echter `Context Entry`
|
|
- braucht nur `order_line_record` aus dem Workflow-Kontext
|
|
- liefert den Großteil des Order-Line-Arbeitskontexts
|
|
- `occ_object_extract`
|
|
- reine `Connection-Driven` Node
|
|
- braucht nur `step_path`
|
|
- keine zusätzlichen lokalen Einstellungen in der Runtime vorhanden
|
|
- `occ_glb_export`
|
|
- reine `Connection-Driven` Node
|
|
- braucht nur `step_path`
|
|
- Registry beschreibt bereits korrekt, dass per-Node-Tessellation-Overrides noch nicht existieren
|
|
- `thumbnail_save`
|
|
- reine `Connection-Driven` Node
|
|
- braucht nur `rendered_image`
|
|
- Verhalten kommt aus dem angeschlossenen Thumbnail-Request, nicht aus lokalen Feldern
|
|
- `stl_cache_generate`
|
|
- reine `Connection-Driven` Kompatibilitäts-Node
|
|
- kein echter Produktionsschritt im HartOMat-Graph
|
|
- Runtime ist bewusst ein `compatibility_noop`
|
|
|
|
### B. Nodes ohne große Feldoberfläche, aber mit wichtiger Laufzeitsemantik
|
|
|
|
- `output_save`
|
|
- hat nur wenige lokale Felder, aber relevante Handoff-Semantik
|
|
- Verhalten hängt von angeschlossenen Render-Artefakten, Shadow/Graph-Mode und Publish-Handoff ab
|
|
- UI muss klarer kommunizieren, wann diese Node `pending`, `completed` oder `failed` wird
|
|
- `notify`
|
|
- hat nur minimale lokale Konfiguration, ist aber stark vom bewaffneten Render-Handoff abhängig
|
|
- in `shadow` wird die Node bewusst unterdrückt
|
|
- braucht vor allem bessere Preflight-/Inspector-Erklärung, nicht mehr Freitextfelder
|
|
- `export_blend`
|
|
- aktuell nur ein bewusst schmaler Bridge-Export
|
|
- nur Dateinamensuffix ist pro Workflow authorbar
|
|
- größere Feldoberfläche wäre aktuell Fake-Konfiguration ohne Runtime-Nutzen
|
|
|
|
### C. Nodes mit dynamischen statt statischen Inputs
|
|
|
|
- `resolve_template`
|
|
- statische Inspector-Felder sind vorhanden
|
|
- zusätzliche Inputs entstehen dynamisch über `workflow_input_schema`
|
|
- das ist keine 0-Felder-Node, aber eine wichtige Ursache für Verwirrung, wenn Template-Inputs im Editor nicht klar sichtbar werden
|
|
|
|
### D. Bewertung
|
|
|
|
- Für Batch A/B ist die Hauptlücke nicht "mehr Felder um jeden Preis".
|
|
- Die Hauptlücke ist:
|
|
- Root-Kontext korrekt modellieren
|
|
- Connection-vs-Inspector-Semantik explizit machen
|
|
- Handoff-/Template-/Shadow-Semantik sichtbarer machen
|
|
- Echte neue Eingabevariablen werden erst dort ergänzt, wo Runtime und Template-System sie tatsächlich unterstützen.
|
|
|
|
## Finding 5: `notify` had a real frontend/backend contract drift
|
|
|
|
Betroffen:
|
|
|
|
- Frontend-Authoring erlaubte `export_blend -> notify`
|
|
- Backend-Schema ließ `notify` bislang nicht auf `blend_asset` reagieren
|
|
|
|
Root cause:
|
|
|
|
- Frontend ergänzte `blend_asset` als alternatives `requires_any`
|
|
- Backend-Registry führte für `notify` nur Render-Artefakte und `workflow_result`
|
|
|
|
Folge:
|
|
|
|
- derselbe Graph konnte im Editor plausibel aussehen, aber beim Backend-Schema scheitern
|
|
- besonders Blend-Export-Workflows waren dadurch inkonsistent authorbar
|
|
|
|
Maßnahme:
|
|
|
|
- `notify.input_contract.requires_any` enthält jetzt auch `blend_asset`
|
|
- Registry führt `blend_asset` auch als konsumiertes Artefakt
|
|
- Schema- und Executor-Tests decken `export_blend -> notify` jetzt explizit ab
|
|
|
|
## Finding 6: Bridge-node runtime params need explicit anti-drift guards
|
|
|
|
Betroffen:
|
|
|
|
- `resolve_template`
|
|
- `material_map_resolve`
|
|
- `auto_populate_materials`
|
|
- `glb_bbox`
|
|
- `output_save`
|
|
- `notify`
|
|
|
|
Root cause:
|
|
|
|
- Core-Render-Nodes waren bereits per Runtime-Key-Tests abgesichert.
|
|
- Bridge-Nodes hatten zwar Registry-Felder, aber keinen zentralen Runtime-Param-Contract gegen Drift.
|
|
|
|
Folge:
|
|
|
|
- zukünftige Änderungen in Runtime oder Registry könnten still auseinanderlaufen
|
|
- besonders gefährlich für Inspector-Felder, die klein wirken, aber produktionskritische Handoff-Semantik steuern
|
|
|
|
Maßnahme:
|
|
|
|
- Runtime-Key-Sets für die Bridge-Nodes wurden in `workflow_graph_runtime.py` zentralisiert
|
|
- Registry-Tests prüfen diese Nodes jetzt 1:1 gegen die Runtime
|
|
|
|
Ergebnis:
|
|
|
|
- Block 6 ist auf Contract-Ebene abgeschlossen
|
|
- weitere Batch-B-Arbeit kann sich jetzt auf Template-/Output-Semantik statt auf Grundsatzdrift konzentrieren
|
|
|
|
## Finding 7: Template workflow inputs were only fully visible after forcing a concrete template override
|
|
|
|
Betroffen:
|
|
|
|
- `resolve_template` im Workflow-Inspector
|
|
|
|
Root cause:
|
|
|
|
- Template-definierte Produktionsvariablen kamen technisch aus `workflow_input_schema`, wurden im Editor aber primär erst nach Auswahl eines festen Template-Overrides sichtbar.
|
|
- Damit blieb ein Teil des realen Authoring-Vertrags für automatische Template-Auflösung zu implizit.
|
|
|
|
Folge:
|
|
|
|
- Autoren konnten schwer erkennen, welche Workflow-Variablen aktive Templates grundsätzlich bereits verlangen oder anbieten.
|
|
- Das machte Template-First-Graphen unnötig intransparent, obwohl die Runtime die Inputs bereits unterstützt.
|
|
|
|
Maßnahme:
|
|
|
|
- der Inspector zeigt jetzt zusätzlich eine automatische Abdeckungsansicht über aktive Templates mit Workflow-Inputs
|
|
- potenzielle Template-Variablen werden vor Auswahl eines festen Overrides als reale Produktionsvariablen sichtbar
|
|
- gezielte Frontend-Tests prüfen sowohl explizite Override-Inputs als auch die automatische Coverage
|
|
|
|
## Finding 8: Render override fields could be edited although runtime discarded them
|
|
|
|
Betroffen:
|
|
|
|
- `blender_still`
|
|
- `blender_turntable`
|
|
|
|
Root cause:
|
|
|
|
- der Inspector behandelte mehrere renderautoritative Felder wie normale Node-Variablen
|
|
- die Runtime verwirft diese Werte jedoch bewusst, solange `use_custom_render_settings` deaktiviert bleibt und Output Type bzw. Template autoritativ sind
|
|
|
|
Folge:
|
|
|
|
- Autoren konnten Konfigurationen eingeben, die im Lauf keine Wirkung hatten
|
|
- das war eine echte Contract-Lücke zwischen UI und Runtime, nicht nur eine Darstellungsfrage
|
|
|
|
Maßnahme:
|
|
|
|
- renderautoritative Felder werden nun gesperrt, bis `use_custom_render_settings` aktiviert ist
|
|
- `output_save` und `notify` dokumentieren zusätzlich ihre Handoff-Semantik im Inspector explizit, um Shadow-/Graph-/Legacy-Verhalten klarer zu machen
|
|
- fokussierte Frontend- und Backend-Tests sichern diese Contract-Regeln gegen Regressions ab
|