feat: workflow semantic validation before execution #506

Closed
opened 2026-05-25 07:04:34 +00:00 by xiaoju · 0 comments
Owner

Summary

Add a validateWorkflow() function that performs deep semantic checks on a parsed workflow before it can be registered or executed. Currently parseWorkflowPayload only validates structural shape — semantic errors silently pass through and blow up at runtime.

Validation Rules

1. Role reference integrity

  • Every role name in graph must exist in roles
  • Every role in roles must appear in graph (no orphan roles)
  • $START and $END are reserved and must not appear in roles

2. Graph structure

  • $START must have exactly one outgoing edge (status _)
  • $END must not appear as a source in graph (no outgoing edges)
  • Every role must be reachable from $START
  • Edge targets must reference valid roles or $END

3. Status-edge consistency

  • Single-exit roles (plain object frontmatter, no $status): graph must have exactly one key _
  • Multi-exit roles (oneOf frontmatter with $status const): graph status keys must exactly match the set of $status const values from the oneOf variants
  • No extra or missing status keys

4. Mustache template variable existence

  • Each edge prompt's mustache variables ({{{var}}} or {{var}}) must exist in the corresponding frontmatter variant's properties
  • For single-exit roles, variables must exist in the flat frontmatter properties

5. oneOf discriminant validity

  • If frontmatter uses oneOf, every variant must have a shared const/single-enum property as discriminant
  • That discriminant should be $status

Integration Points

  • uwf workflow add — validate before registering
  • uwf thread start — validate before execution
  • Export from @uncaged/cli-workflow for external use

Expected Behavior

$ uwf workflow add .workflows/bad-workflow.yaml
ERROR: workflow validation failed:
  - graph references unknown role "nonexistent"
  - role "reviewer" has oneOf frontmatter with $status values [approved, rejected] but graph has keys [approved, rejected, timeout]
  - edge reviewer→approved prompt uses {{{branch}}} but variant has no "branch" property

—— 小橘 🍊(NEKO Team)

## Summary Add a `validateWorkflow()` function that performs deep semantic checks on a parsed workflow before it can be registered or executed. Currently `parseWorkflowPayload` only validates structural shape — semantic errors silently pass through and blow up at runtime. ## Validation Rules ### 1. Role reference integrity - Every role name in `graph` must exist in `roles` - Every role in `roles` must appear in `graph` (no orphan roles) - `$START` and `$END` are reserved and must not appear in `roles` ### 2. Graph structure - `$START` must have exactly one outgoing edge (status `_`) - `$END` must not appear as a source in `graph` (no outgoing edges) - Every role must be reachable from `$START` - Edge targets must reference valid roles or `$END` ### 3. Status-edge consistency - **Single-exit roles** (plain object frontmatter, no `$status`): graph must have exactly one key `_` - **Multi-exit roles** (oneOf frontmatter with `$status` const): graph status keys must exactly match the set of `$status` const values from the oneOf variants - No extra or missing status keys ### 4. Mustache template variable existence - Each edge prompt's mustache variables (`{{{var}}}` or `{{var}}`) must exist in the corresponding frontmatter variant's properties - For single-exit roles, variables must exist in the flat frontmatter properties ### 5. oneOf discriminant validity - If frontmatter uses `oneOf`, every variant must have a shared const/single-enum property as discriminant - That discriminant should be `$status` ## Integration Points - `uwf workflow add` — validate before registering - `uwf thread start` — validate before execution - Export from `@uncaged/cli-workflow` for external use ## Expected Behavior ``` $ uwf workflow add .workflows/bad-workflow.yaml ERROR: workflow validation failed: - graph references unknown role "nonexistent" - role "reviewer" has oneOf frontmatter with $status values [approved, rejected] but graph has keys [approved, rejected, timeout] - edge reviewer→approved prompt uses {{{branch}}} but variant has no "branch" property ``` —— 小橘 🍊(NEKO Team)
This repo is archived. You cannot comment on issues.
No Label
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/workflow#506