Skip to content

Workflow Workspace Editor Spec

Status

Current architecture + implementation status after editor v0.2.0.

Implemented:

  • common editor Filetree workspace view,
  • embedded platform workspace discovery by top-level path segment,
  • embedded Export Workspace from deployed baseline,
  • directory export where File System Access API is available,
  • ZIP export fallback for other browsers,
  • standalone Open Workspace from directory or ZIP,
  • workspace import validation,
  • standalone in-memory baseline/current snapshot,
  • draft create/rename/delete in standalone memory.

Not implemented yet:

  • durable BrowserWorkspaceStore,
  • Save Workspace to disk,
  • Deploy Workspace changed-only diff flow,
  • mandatory Save/Deploy change review dialog,
  • dynamic namespace creation,
  • workflow versioning/history semantics.

Goal

Move workflows between the embedded eFEC platform editor and the standalone editor without bypassing governance.

Current user flow:

text Platform editor -> File / Export Workspace -> folder or zip Standalone editor -> File / Open Workspace -> folder or zip

Future user flow:

```text Embedded: PlatformDeployedWorkspaceStore -> BrowserWorkspaceStore -> Deploy changed workflows via process_event

Standalone: FileSystemWorkspaceStore -> BrowserWorkspaceStore -> Save changed workflows to disk ```

Canonical identity

A workflow definition declares:

json { "$version": "2.0", "$path": "customer/retail/retail-customer" }

Workspace file path must match:

text customer/retail/retail-customer.json

Rules:

  • $path is the workflow identity.
  • Storage path is $path + ".json".
  • File path and $path must match.
  • Spawn references use canonical workflow paths.
  • $category is forbidden in active/imported/exported definitions.

Current editor layout

The common editor is platform-agnostic and receives workspaceFiles from its host.

Layout:

text Menu bar ├─ Filetree sidebar ─ Main view │ ├─ Breadcrumb bar │ ├─ JSON | Graph tabs │ └─ JSON editor or Graph canvas Bottom/status bar

Behavior:

  • Filetree is persistent and can be collapsed.
  • Folders expand/collapse with +/-.
  • Clicking a workflow opens Graph by default.
  • JSON remains available in the left tab.
  • Graph auto-fits after paint in both embedded and standalone modes.
  • Graph side panels (States/Actions and Inspector/Validate) open collapsed by default.
  • Preferences are internal to the common editor.

Current embedded platform behavior

Admin derives workspace rows dynamically from get_workflows() by first path segment:

text case customer demo product screening system

Opening a row routes to:

text /admin/workflows?workspace=<workspace>

The platform wrapper filters deployed workflows to that top-level workspace and passes only that subset to the common editor.

Deep links still work by canonical path:

text /admin/workflows/customer/retail/retail-customer

The selected workspace is derived from the first path segment.

Current Export Workspace behavior

File -> Export Workspace in the embedded platform exports the selected top-level workspace subset from deployed registries.

Sources:

  • get_workflows() list,
  • get_workflow(path) details.

Outputs:

text <workflow.$path>.json workspace.json

Examples for customer:

text customer/retail/retail-customer.json customer/corporate/corporate-customer.json workspace.json

Export mechanisms:

  • directory picker when showDirectoryPicker is available,
  • ZIP download fallback otherwise.

ZIP filename:

text <workspace>-workflow-workspace.zip

Manifest shape:

json { "$schema": "https://efec.dev/schemas/workflow-workspace-v1.json", "exported_at": "2026-06-18T00:00:00.000Z", "source": "fec_platform", "workflow_count": 17, "workflows": ["customer/retail/retail-customer"] }

Manifest is metadata only. Workflow JSON files are authoritative.

Export validation blocks:

  • missing/string-invalid $path,
  • list/detail/definition path mismatch,
  • duplicate $path,
  • recursive $category,
  • basename -Vn,
  • invalid canonical path shape,
  • unresolved spawn.workflow,
  • output path mismatch.

system/bootstrap is exportable. Non-system */bootstrap workflows should not exist after reset/reseed and are not expected in exports.

Current standalone Open Workspace behavior

Standalone editor supports File -> Open Workspace.

Input modes:

  • directory workspace via File System Access API,
  • ZIP workspace via file picker fallback.

Import behavior:

  • recursively reads .json files,
  • treats workspace.json as optional metadata, not a workflow,
  • validates all files before replacing the current in-memory workspace,
  • initial selection is empty with Filetree visible,
  • clicking a workflow opens Graph by default.

Standalone stores a session-local snapshot:

ts type WorkspaceSnapshot = { baseline: Record<string, WorkflowDef>; current: Record<string, WorkflowDef>; };

Baseline/current are separate copies. Dirty flags are computed by stable JSON comparison. This is in-memory only; durable browser storage is future work.

Import validation blocks:

  • non-object workflow JSON,
  • missing/string-invalid $path,
  • relative path mismatch vs $path + '.json',
  • recursive $category,
  • duplicate $path,
  • basename -Vn,
  • unresolved spawn.workflow,
  • workflow validator errors,
  • unsafe ZIP paths.

Import warnings are allowed and shown as dismissible feedback. Validator success/info messages such as All checks passed are not warnings.

Future storage model

The target architecture still uses a shared workspace store abstraction:

Adapter Role
BrowserWorkspaceStore durable active working copy for embedded and standalone editor
PlatformDeployedWorkspaceStore read-only deployed baseline
FileSystemWorkspaceStore standalone source/sink for Open/Save Workspace
MemoryWorkspaceStore tests

Core interface:

ts export interface WorkflowWorkspaceStore { list(): Promise<string[]>; read(path: string): Promise<string>; write(path: string, content: string): Promise<void>; delete(path: string): Promise<void>; exists(path: string): Promise<boolean>; }

Rules:

  • core service does not call platform APIs,
  • core service does not call browser file APIs directly,
  • adapters own environment-specific IO,
  • import writes browser draft only,
  • platform deployment always uses signed process_event.

Future diff and change-set model

Save Workspace and Deploy Workspace must compute a baseline/current diff before writing anything.

Comparison key:

text workflow.$path

Statuses:

Status Meaning Embedded Deploy Standalone Save Workspace
added exists in current, not baseline include in deployment write new file
changed exists in both, canonical definition differs include in deployment overwrite file
unchanged same canonical definition exclude exclude
deleted baseline exists, current missing report only in v1 report only in v1

Rules:

  • only added and changed are actionable in v1,
  • unchanged workflows are excluded,
  • deletions are reported but not applied,
  • canonical JSON comparison ignores formatting/key-order differences,
  • change review is mandatory before Save/Deploy.

Future mandatory change review dialog

Before Deploy or Save Workspace, show a dialog listing:

  • added workflows,
  • changed workflows,
  • deleted workflows detected but unsupported,
  • unchanged count,
  • validation status,
  • target namespaces or file paths,
  • exact number of deployment events or file writes.

Primary action disabled when:

  • validation fails,
  • no changes exist,
  • unsupported deletions exist.

Future embedded Deploy Workspace model

Deploy from embedded editor:

  1. load deployed baseline,
  2. load browser working copy,
  3. validate workspace,
  4. compute diff,
  5. show mandatory review,
  6. group added/changed workflows by dirname($path),
  7. submit signed process_event deployment events,
  8. include only changed workflows,
  9. update baseline metadata after success.

No raw registry writes.

Future standalone Save Workspace model

Save from standalone editor:

  1. load filesystem baseline,
  2. load browser working copy,
  3. validate workspace,
  4. compute diff,
  5. show mandatory review,
  6. write only added/changed files,
  7. report but do not delete missing baseline files,
  8. update baseline metadata after success.

No platform/API dependency.

Guardrails

Current and future implementation must preserve:

  • file path equals $path + '.json',
  • no $category,
  • no v1 workflow definitions,
  • no -Vn active names,
  • spawn refs resolve,
  • export/import validates before state replacement or download,
  • platform deploy uses process_event only,
  • no direct DB registry mutation.

Open questions for later

  • Save Workspace implementation and browser persistence.
  • Deploy Workspace changed-only implementation.
  • Conflict resolution when baseline changes during editing.
  • Workflow deletion/retirement semantics.
  • Workflow deployment approval workflow.
  • Immutable workflow versioning/history semantics.