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:
$pathis the workflow identity.- Storage path is
$path + ".json". - File path and
$pathmust match. - Spawn references use canonical workflow paths.
$categoryis 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
showDirectoryPickeris 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
.jsonfiles, - treats
workspace.jsonas 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
addedandchangedare 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:
- load deployed baseline,
- load browser working copy,
- validate workspace,
- compute diff,
- show mandatory review,
- group added/changed workflows by
dirname($path), - submit signed
process_eventdeployment events, - include only changed workflows,
- update baseline metadata after success.
No raw registry writes.
Future standalone Save Workspace model¶
Save from standalone editor:
- load filesystem baseline,
- load browser working copy,
- validate workspace,
- compute diff,
- show mandatory review,
- write only added/changed files,
- report but do not delete missing baseline files,
- 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
-Vnactive names, - spawn refs resolve,
- export/import validates before state replacement or download,
- platform deploy uses
process_eventonly, - 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.