fix: workflow blueprints freely editable after creation (preserve_user_graph)

canonicalize_workflow_config was silently rebuilding any workflow with
ui.blueprint or ui.preset == still_graph from the canonical template on
every save, preflight, and read — making blueprint-based workflows
effectively read-only.

Add preserve_user_graph=True flag that skips the rebuild blocks. Only
create_workflow still uses preserve_user_graph=False so blueprints are
correctly expanded at creation time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 11:17:32 +02:00
co-authored by Claude Sonnet 4.6
parent 4ea6c4ee9c
commit 53b19f2ba1
3 changed files with 33 additions and 28 deletions
@@ -264,7 +264,7 @@ async def _build_rollout_summary(
async def _workflow_to_out(db: AsyncSession, wf: WorkflowDefinition) -> WorkflowDefinitionOut:
canonical_config = canonicalize_workflow_config(wf.config)
canonical_config = canonicalize_workflow_config(wf.config, preserve_user_graph=True)
workflow_family = infer_workflow_family_from_config(canonical_config)
supported_artifact_kinds = tuple(
derive_supported_artifact_kinds_from_workflow_config(canonical_config)
@@ -408,7 +408,7 @@ def _build_workflow_preflight_for_config(
submit_prepared_workflow_tasks,
)
normalized_config = canonicalize_workflow_config(workflow_config)
normalized_config = canonicalize_workflow_config(workflow_config, preserve_user_graph=True)
try:
workflow_context = prepare_workflow_context(
normalized_config,
@@ -942,7 +942,7 @@ async def update_workflow(
wf.name = body.name
if body.config is not None:
try:
normalized_config = canonicalize_workflow_config(body.config)
normalized_config = canonicalize_workflow_config(body.config, preserve_user_graph=True)
WorkflowConfig.model_validate(normalized_config)
except (ValidationError, ValueError) as exc:
detail = exc.errors() if isinstance(exc, ValidationError) else str(exc)
@@ -1033,7 +1033,7 @@ async def _dispatch_workflow_for_config(
)
try:
normalized_config = canonicalize_workflow_config(workflow_config)
normalized_config = canonicalize_workflow_config(workflow_config, preserve_user_graph=True)
workflow_context = prepare_workflow_context(
normalized_config,
context_id=context_id,