Workflow Versioning
Proposal for formal versioning system for workflows
Workflow Versioning Architecture
Source: This page is based on docs/PROPOSALS/WORKFLOW_VERSIONING.md
Last Updated: January 15, 2026
Introduction & Motivation
This document outlines the design for a formal versioning system for workflows in Project Eddy. The goal is to enhance the platform's robustness, support compliance and audit requirements, and provide a safe mechanism for editing live, in-production processes.
Our current Draft/Published model, controlled by the published_at column, serves as a basic lifecycle gate. However, it has limitations:
- It encourages "reverting to draft," which can be disruptive for live processes
- It doesn't preserve a clear history of how a process has changed over time
The proposed versioning system leverages our existing copyWorkflow service, making our implicit "forking" capability an explicit, first-class feature for iterative process development.
Core Concepts
To implement this system, we will introduce the concept of a Workflow Family.
- Workflow Family: A collection of all versions of a single logical workflow, linked together. For example, "Client Onboarding" is a family, which might contain v1, v2, and v3.
- Workflow Version: A specific, immutable snapshot of a workflow within a family. Each version has a unique
idin theworkflowstable. - Active Version: The single, published version within a family that is used to start new
workflow_runs. This is the "live" or "production" version. - Draft Version: An unpublished, editable version of a workflow. There can only be one draft version per family at a time (the "latest" version).
- Archived Version: A previously published version that has been superseded by a newer active version. It is preserved for historical
workflow_runsbut cannot be used to start new ones.
Core principle: Published workflows are immutable. To change a published workflow, a user must create a new draft version.
Implementation Plan
Database Schema Changes
Proposed additions to workflows table:
| Column | Type | Constraints | Description |
|---|---|---|---|
parent_workflow_id | uuid | FK → self | Groups versions into a family. Points to the ID of the first-ever version (v1). |
version | integer | NOT NULL | The version number (1, 2, 3...), incrementing within a family. |
is_latest_version | boolean | NOT NULL | A flag to quickly identify the latest version in a family (which is the current draft). |
source_workflow_idwill continue to point to the immediate predecessor from which a version was createdparent_workflow_idwill be the key to group all versions of a family together- For a new workflow (v1),
parent_workflow_idwill be its ownid
API & Service Layer Changes
1. "Create New Version" Action
Endpoint: POST /api/workflows/:id/version
Service Logic (createWorkflowVersion):
- Find the latest version in the family (
is_latest_version = true) - Call
copyWorkflowto create a full duplicate of this latest version - On the new workflow record:
published_atis set toNULLparent_workflow_idis set to the family'sparent_workflow_idsource_workflow_idis set to the ID of the workflow it was copied fromversionis incremented from the previous version numberis_latest_versionis set totrue
- On the old workflow record:
- Its
is_latest_versionflag is set tofalse
- Its
2. "Publish Version" Action
Endpoint: POST /api/workflows/:id/publish (Modify existing)
Service Logic:
- The user can only publish the latest draft version (
is_latest_version = trueandpublished_at IS NULL) - Set
published_atto the current timestamp on the draft version - Find the previous active version in the family
- Set
archived_aton the previous active version. This gracefully retires it
3. Enforcing Immutability
- A new authorization check will be added to all workflow builder mutation endpoints
- This check will run before any other logic. It will fetch the workflow and inspect its
published_atcolumn - If
published_atis NOT NULL, the API will return a403 Forbiddenerror with the message: "Cannot edit a published workflow. Please create a new version to make changes."
Frontend (UI/UX) Changes
1. Workflow Builder
- When viewing a published workflow, the UI will enter a "read-only" mode
- A prominent banner will be displayed: "You are viewing a published version (v2). To make changes, create a new version."
- The "Publish" button will be replaced with a "Create New Version" button
- Versioning Warning: When a user clicks "Create New Version" or "Publish," a confirmation modal will appear clearly stating the impact on Start Links
2. Workflow List Page
- The list will be updated to group workflow families
- Instead of multiple rows, there will be one row per family, displaying the name and the latest active version number (e.g., "Client Onboarding - v3 (Active)")
- An expandable section or a separate "Version History" page will show all versions (drafts, active, archived) for that family
3. Copy vs. Version
The distinction will be clear:
- Copy Workflow: Creates a brand new, independent workflow family. Useful for starting a new process based on an existing template.
- Create New Version: Creates the next iteration of the same workflow family. Used for updates and improvements.
Impact on Existing Systems
Workflow Runs
No changes are needed to workflow_runs. Each run is already tied to a specific workflow_id, which now represents a specific version. In-flight runs will safely continue on their original version even after a new version is published.
Self-Service Start Links
When a new workflow version is published, the previously active version will be archived. This action will cascade and automatically archive all self_service_starts records associated with the old version.
- Starting New Sessions: Archived Start Links cannot be used to initiate new sessions
- Resuming Existing Sessions: The public start page will continue to function for users who need to find and resume in-progress sessions that were initiated before the link was archived
Analytics
Reporting queries will need to be updated. To get metrics for the "Client Onboarding" process over time, queries will need to GROUP BY parent_workflow_id.
Migration Strategy
A one-time database migration will be required to bring existing workflows into the new versioning system.
The script will iterate through all workflows where parent_workflow_id is NULL. For each of these, it will set:
parent_workflow_id=id(it becomes the first in its family)version=1is_latest_version=true
Rollback Capability
Core Logic
A "Rollback" feature allows a user to revert the active version of a workflow family to a previously published version.
Use Case: A new version (v3) is published, but a critical bug is discovered. The admin wants to immediately revert to v2 while a fix is developed.
Implementation
Endpoint: POST /api/workflows/:id/rollback
Service Logic:
- Verify the target workflow is an archived version (has
archived_atset) - Find the current active version in the family
- Archive the current active version (set
archived_at) - Unarchive the target version (set
archived_attoNULL) - Update Start Links to point to the rolled-back version
Advanced Versioning Modes & Compliance
Workflow Lifecycle Stages
For compliance-critical workflows, we can introduce additional lifecycle stages:
- Draft - Editable, not published
- Published - Active, immutable
- Certified - Audited and approved for use
- Locked - Cannot be versioned or modified without special permission
- Archived - Superseded by newer version
Compliance and Locking Levels
Level 1: Standard (Current System)
- Workflows can be versioned freely
- Published workflows are immutable
Level 2: Certified Workflows
- Require approval before publishing
- Maintain audit trail of all changes
- Cannot be archived without documentation
Level 3: Locked Workflows
- Require special permission to create new versions
- All changes must be documented and approved
- Complete audit trail required