Skip to content

✨ Workflow models: visual editor with live compile, YAML, diff, simulate and export - #17706

Merged
hivecommons-hive[bot] merged 14 commits into
v5from
workflowmodel/v5-p4-editor
Nov 11, 2026
Merged

hivecommons-hive[bot] merged 14 commits into
v5from
workflowmodel/v5-p4-editor

Conversation

@clubanderson

@clubanderson clubanderson commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

RFC phase 4 (UI) of #17620 on v5: the workflow-model Editor — a real design surface for state machines (lanes, chips, edges, drag/drop, live compile), not a form over the JSON. Follows the owner's brief: "the editor needs to be a good design tool too".

Stacked on the merged Workflows-tab (#17681) and Simulate (#17688) PRs. Includes the remainder of #17685 (P4 backend) until it merges — after rebasing on v5 that is only its changelog fragment and the route registration line.

Screenshots (hive-default copy, 22 states / 91 transitions)

Quiet default — orthogonal gutter routing, one bundled trunk per lane pair, no edge labels:

editor canvas, quiet default

Focus mode — hovering claimed dims non-incident edges and lifts its 12 in/out edges to the front:

focus mode on claimed

What

Settings → Workflows gains an Editor nav item plus Edit buttons on library rows and the detail view (owner only; hive-default offers Edit a copy). The ingest result gains Open in editor.

Layout: toolbar · templates palette · SVG canvas · inspector · bottom drawer (Problems · YAML · Diff · Simulate).

Interaction model

  • Columns are lanes: add, rename (dbl-click header), reorder by dragging the header, resize with snap-to-grid, toggle terminal (shaded), delete (moves or deletes its states after confirm).
  • States are chips: drag within/between lanes (updates lifecycle.column + order), dbl-click rename, Delete/Backspace, marquee multi-select, shift-click, arrow-key nudge, tabindex=0 + Enter/Delete for keyboard users.
  • Transitions: drag from a chip's right-edge port to another chip; defaults on: '' and focuses the inspector field. Edges use a quiet-by-default, detail-on-focus layer shared with the library diagram (design feedback on the hive-default knot): orthogonal routing through the lane gutters with one bundled trunk per lane pair, same-lane edges stacked on the lane margin, lane-skipping edges in corridors outside the lanes (backward ones above the headers, dashed/muted), no edge labels by default (hover/select an edge for its pill label; a Labels toggle labels only the exceptional events — the most common on such as stage-change never), focus mode (hover/select a state → non-incident edges dim, incident edges come to the front in the accent colour with arrowheads; hovering an edge highlights both end chips), and fan-out collapse (>4 edges from one state into one lane → one trunk with a +N badge; hover expands, click pins). Pure router wfRouteEdges / wfOrthoPath / wfEdgeChannels / wfEdgeCommonEvent with node tests (bundling by lane pair, back edge outside, adjacent back edge in the gutter, labels hidden by default, common event tagged, fan threshold and expansion, determinism).
  • Pan (wheel / space+drag / middle button), zoom (Ctrl/Cmd+wheel, ± / Fit), minimap when the model overflows, Auto-layout (topological lane order, stage-number order within lanes).
  • Compile badges on chips/edges/columns with tooltips; inferred elements dashed with a one-click ✓ confirm; initial-state marker.
  • Palette: common states (ids/kinds/stage numbers), common columns, and hive-default stages (fetched once). Drops assign unique slugified ids.
  • Inspector: state (id + rename with reference update, label, column, stage number, owner, type, kinds, confidence, replies, citations), transition (on with declared-events datalist, guard, note), column (id, label, hint, terminal), model (name, description, source, provenance, version, derivation, initial, label prefix, scope repo).
  • Live compile (300 ms debounce) → POST /api/workflows/compile; status pill compiles / N warnings / does not compile; Problems drawer click-to-select; instant client-side mirror of the compiler's refusals (wfEdLocalProblems).
  • YAML drawer: two-way (model→yaml debounced while the tab is visible and unfocused; yaml→model on Apply with inline parse errors).
  • Diff drawer: client-side structural diff of the working copy vs last saved (wfEdDiff, same shape as Go ModelDiff), plus stored-version diff via GET …/diff.
  • Simulate drawer: compact fact table → POST /api/workflows/simulate {model, kind, facts} for the unsaved model; decided state highlighted (.wf-ed-sim-hit), others dimmed; reason + trace shown.
  • History: undo/redo (Cmd/Ctrl-Z, Shift-Cmd-Z), capped snapshot stack, dirty indicator; Save posts with meta.version: '' so the store assigns the next integer, then reloads the library and reopens the saved entry; Save as…, Revert, leave-guard via hiveConfirm.
  • Start screen: new blank model, duplicate hive-default, open from library, last ingest result, marketplace placeholder (phase 7).
  • Export: SVG (self-contained, theme tokens resolved from the canvas), PNG (rasterised, shown inline with open-in-new-tab — no forced downloads), model JSON, model YAML.

Pure core (no DOM, node-tested)

wfEdNewModel, wfEdAddColumn, wfEdMoveColumn, wfEdRemoveColumn, wfEdAddState, wfEdMoveState, wfEdRenameState, wfEdRemoveState, wfEdAddTransition, wfEdUpdate, wfEdUniqueId, wfEdAutoLayout, wfEdLayout, wfEdDiff, wfEdLocalProblems, wfEdSvg, wfEdMinimapSvg, wfEdStatus. All deterministic and non-mutating; workflows_editor_ui_test.go runs them under node from the generated bundle.

APIs added

  • POST /api/workflows/yaml — {model} → {yaml} and {yaml} → {model, error?} (JSON→YAML so field names match json tags).
  • POST /api/workflows/simulate — {model, kind, facts} for an unsaved model; same response shape as the stored-model variant (reuses stageengine.Explain).
  • POST /api/workflows now assigns the next integer version when meta.version is empty.
    All in dashboard/openapi.json with handler tests; read-only computations need no owner role (mirrors the GET handlers).

Guards

Plain JS/CSS in the concatenated bundle (no libraries); CSS tokens only; no toLocaleString; no forced downloads; all actions delegated via data-action except the canvas pointer listeners attached idempotently after each render. Style/import/history-cap/band-wiring ratchets, openapi route coverage, settings-search and deeplink tests pass; gen -check clean.

Verified in a browser (Chrome via CDP against a local dashboard)

New model → 3 columns → palette drops → port-drag transitions (incl. backward) → chip drag between lanes → header drag reorder → lane resize → marquee → Delete → Cmd-Z / Shift-Cmd-Z → compile pill + Problems → YAML edit → Apply (and a parse error shown inline) → Simulate highlighting the decided state → Save (v1) → edit → client diff → Save (v2) → stored-version diff → Export SVG/PNG/JSON/YAML → Library Edit reopen → hive-default Edit a copy → leave guard. Bugs found by the smoke test (YAML newlines lost through esc(), focus lost after re-render, dark export colours in light theme, crowded edge labels) are fixed in this PR.

Docs

docs/design/workflow-models.md — new "Editor (RFC phase 4, UI)" section; changelog.d/added-workflowmodel-editor.md.

Deferred

Editing events/gates/roles/rules on the canvas (available through the YAML drawer); nested regions beyond flattening; marketplace (phase 7); keyboard-only lane reorder; collaborative/locking semantics; persisted lane widths.

Refs #17620

…Defs, store.NextVersion

Pure, deterministic model diff (columns/states/transitions/labels/rules/meta),
Confirm that clears inferred confidence and localises provenance, the label
vocabulary a profile reconciles, and the store's next free integer version.

Refs #17620

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
GET /api/workflows/{name}/versions, GET /api/workflows/{name}/diff?from&to
(fromName/toName for cross-model), POST .../{version}/confirm (owner,
audited workflow_confirm, 409 for hive-default) and GET .../{version}/labels.
Documented in dashboard/openapi.json.

Refs #17620

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
… rebind

ensureStageLabels asks the stage engine's WorkflowFor lookup for the profile
bound to the repository and creates or recolours its LabelDefs after the
built-in family, memoised per repo and profile hash so a binding change takes
effect on the next pass. Unbound repositories take the pre-existing path
unchanged. Design doc section and changelog fragment.

Refs #17620

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
…o workflowmodel/v5-p4-editor

# Conflicts:
#	dashboard/openapi.json
#	src/docs/design/workflow-models.md
#	src/pkg/dashboard/api_workflows.go
Adds POST /api/workflows/yaml (model <-> YAML, inline errors) and
POST /api/workflows/simulate (body model + facts, same shape as the
stored-model variant), and lets POST /api/workflows assign the next
free version when meta.version is empty so the editor's Save never has
to guess. OpenAPI entries and handler tests included.

Refs #17620

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
(cherry picked from commit d8949480e0f33151bb7417f6d370519246cbf70a)
Adds js/config-workflows-editor.js (pure model/layout/diff/problems/svg
core plus the runtime: SVG canvas with lanes, chips, ports and edges;
drag, marquee, pan/zoom, minimap; palette; inspector; Problems/YAML/Diff/
Simulate drawers; undo/redo; save/save-as/revert; export) with
css/workflows-editor.css, wires the Editor nav item, Edit / Edit-a-copy
buttons and the ingest 'Open in editor' affordance into the library, and
pins the pure core under node in workflows_editor_ui_test.go.

Refs #17620

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
(cherry picked from commit 16812a4519330e7bedfe955d816e425b45d0a94a)
…gelog

Fix the YAML drawer losing newlines through esc(), restore canvas focus after
re-render so undo/redo shortcuts keep working, resolve export theme tokens from
the canvas element (light theme exported dark), hide edge labels on dense
models unless selected, and tighten inspector field layout. Append the Editor
section to docs/design/workflow-models.md and add the changelog fragment.

Refs #17620

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
(cherry picked from commit 2c94cade8ea85a0b807366ac91c2a4b3edf7b736)
@kubestellar-prow kubestellar-prow Bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Nov 11, 2026
@kubestellar-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign hanthor for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubestellar-prow kubestellar-prow Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Nov 11, 2026
@github-actions

github-actions Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Open PR overlap check

Base branch: v5

Conflicts are checked with every PR merged onto the current tip of v5, so a PR that only needs a rebase is not reported as conflicting with its siblings.

PR Title Relation Files
#17714 ✨ Workflow models: signed bundles, hub marketplace catalogue with nightly refresh, spoke import/publish same files dashboard/openapi.json
src/docs/design/workflow-models.md
src/pkg/dashboard/api_workflows.go
src/pkg/dashboard/static-src/js/config-workflows-library.js
src/pkg/dashboard/static-src/manifest.txt
src/pkg/dashboard/static/index.html

@github-actions

Copy link
Copy Markdown
Contributor

Mutation testing

❌ gremlins did not produce a report for 1 package(s), so no verdict can be derived from this run (see the job log):

  • pkg/dashboard: gremlins exited 137

Verdict: error (#17349).

@hivecommons-hive

hivecommons-hive Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Hive status — updated in place; edits do not notify. Full history is in the Activity Monitor.

clubanderson this PR is held at stage/071-needs-author and the hive will not merge it yet.

Why:

  • the branch conflicts with the base and needs a rebase

Next: the hive does not push to your branch. Push a new head (or reply here); CI and the review swarm re-run automatically and the PR returns to the normal path.

Evidence bundle `#17706a8cd2cf` sha256:4a109f0f70260536785547bfeed02f578ece31d958dfa9434e9f59c313adebeb — download from the dashboard or `hivectl review evidence #17706`.

…ng and fan collapse

Replace the one-bezier-per-transition edge layer in the editor canvas and
the read-only library diagram with a shared pure router (wfRouteEdges,
wfOrthoPath, wfEdgeChannels, wfEdgeCommonEvent): orthogonal polylines
through the lane gutters bundled per lane pair, same-lane edges stacked on
the lane margin, lane-skipping edges in corridors outside the lanes (back
edges above the headers, dashed/muted), no edge labels by default (hover or
select an edge, or the Labels toggle which skips the most common event),
focus mode on hover/selection that dims non-incident edges and lifts the
incident ones to the front, and +N fan collapse for >4 edges from one state
into one lane. Node tests cover bundling, back-edge placement, label
visibility, fan threshold and determinism; design doc updated.

Refs #17620

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
@kubestellar-prow kubestellar-prow Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 11, 2026
Signed-off-by: Andrew Anderson <andy@clubanderson.com>

# Conflicts:
#	src/docs/design/workflow-models.md
@kubestellar-prow kubestellar-prow Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 11, 2026
@github-actions github-actions Bot added conflicts-with-open-pr Open PR has a merge conflict with another open PR and removed conflicts-with-open-pr Open PR has a merge conflict with another open PR labels Nov 11, 2026
clubanderson and others added 2 commits November 11, 2026 11:40
Signed-off-by: Andrew Anderson <andy@clubanderson.com>

# Conflicts:
#	src/pkg/dashboard/api_workflows.go
#	src/pkg/dashboard/static-src/manifest.txt
#	src/pkg/dashboard/static/index.html
@hivecommons-hive
hivecommons-hive Bot merged commit 1303369 into v5 Nov 11, 2026
84 of 85 checks passed
@kubestellar-prow
kubestellar-prow Bot deleted the workflowmodel/v5-p4-editor branch November 11, 2026 18:54
@hivecommons-hive

Copy link
Copy Markdown
Contributor

merged by Hive trusted-author auto-merge: author @clubanderson holds role owner and GitHub permission admin on repo; CI green at a8cd2cf.

@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your contribution! Your PR has been merged.

We'd love to hear how your experience was: share feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dco-signoff: yes Indicates the PR's author has signed the DCO. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant