Skip to content

Workflow Path and Namespace Spec

Status

Current implementation spec.

Canonical workflow paths are live across seed data, runtime execution, platform API, Admin workspace discovery, embedded editor routing, workspace export, and standalone workspace import.

Core decision

Canonical $path is the workflow identity.

A workflow path is simultaneously:

  1. the user-facing hierarchical location of a workflow,
  2. the runtime namespace + local workflow key,
  3. the platform API identity,
  4. the editor Filetree identity, and
  5. the workspace file path without .json.

Examples:

text customer/retail/retail-customer customer/corporate/corporate-customer screening/name/name-screening screening/pep/pep-screening product/account/current-account case/review/kyc-review demo/retail/demo-retail-04-spawn-case system/bootstrap

Derived values:

text workspace = first segment of path # customer namespace = dirname(path) # customer/retail workflow = basename(path) # retail-customer registry = namespace-registry id with / replaced by -

There is no separate active category/source organization model. $category is not allowed in active workflow definitions.

Path validation

Workflow path pattern:

text ^[a-z][a-z0-9-]*(/[a-z][a-z0-9-]*)+$

Rules:

  • at least two segments,
  • no empty segments,
  • no . or ..,
  • no basename version suffix like -V1,
  • local workflow key is the basename only,
  • namespace path is everything before the basename.

Process IDs remain separate safe IDs and are not broadly allowed to contain /.

Workflow definition rule

Every non-bootstrap workflow declares its canonical path:

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

Rules:

  • $path is required for all non-bootstrap workflows.
  • $path must be unique in the deployed registry set or imported workspace.
  • Deployment target namespace/key must match dirname($path) and basename($path).
  • Seeded active workflow definitions carry no redundant organization metadata.

Bootstrap rule:

  • system/bootstrap is the only visible/listed bootstrap workflow.
  • Non-system namespace registries are governed by the hardcoded Rust bootstrap workflow internally, but they do not store data.workflows.bootstrap and do not appear as */bootstrap in get_workflows().

Initial namespace set

Source reset creates registry processes for the fixed initial namespaces:

Namespace Workflows after seed
system bootstrap
customer/retail retail customer workflows
customer/corporate corporate customer workflow
screening/name name screening workflow
screening/pep PEP screening workflow
product/account account product workflows
case/review review/case workflows
demo/retail retail demo workflows
demo/kyc KYC demo workflow
demo/case demo child-case workflow

Future work may add governed dynamic namespace creation. Current reset creates only the known registries.

Registry model

Each namespace has one registry process:

text registry process id: <namespace>-registry, with `/` replaced by `-` process.namespace: <namespace> process.workflow: bootstrap process.is_registry: true

Examples:

Namespace Registry process id
system system-registry
customer/retail customer-retail-registry
screening/name screening-name-registry
demo/retail demo-retail-registry

Reset/bootstrap behavior:

  • system-registry stores data.workflows.bootstrap.
  • Non-system registries start with data.workflows = {}.
  • Business/demo workflow definitions are not embedded in schema.sql.
  • Business/demo workflows are deployed by signed process_event events.

Event action workflow semantics

Create/genesis events

For a create/genesis event:

json { "name": "create", "workflow": "customer/retail/retail-customer", "process_id": "jane-doe", "data": {} }

Runtime derives:

text process.namespace = customer/retail process.workflow = retail-customer

action.data.namespace is deprecated for creates. If present during transition, it must match dirname(action.workflow).

Existing-process events

For non-create events:

  • the process is loaded first,
  • dirname(action.workflow) must equal process.namespace,
  • basename(action.workflow) must equal process.workflow,
  • runtime loads workflow by (process.namespace, process.workflow).

No name-only registry search is allowed for execution or flow evaluation.

Registry deployment events

Workflow deployments target the namespace registry process and are still signed events:

json { "name": "add_workflow", "workflow": "customer/retail/bootstrap", "process_id": "customer-retail-registry", "data": { "workflows": { "retail-customer": { "$path": "customer/retail/retail-customer" } } } }

The non-system customer/retail/bootstrap path is an internal governance path, not a stored/listed workflow definition. The engine loads the hardcoded bootstrap workflow for registry processes.

Spawn references

Workflows reference each other by canonical path:

json { "type": "spawn", "workflow": "case/review/kyc-review" }

Rules:

  • full paths only,
  • no relative/local spawn refs,
  • runtime derives target namespace/key from spawn.workflow,
  • runtime validates target workflow existence before creating a child process.

Platform API

get_workflows() returns path-aware workflow list items, including:

json { "path": "customer/retail/retail-customer", "namespace": "customer/retail", "name": "retail-customer", "version": "2.0", "description": "Retail customer onboarding" }

New code uses canonical paths exclusively for lookup and routing.

Admin and editor behavior

Admin discovers top-level workspaces dynamically from deployed workflow paths:

text case customer demo product screening system

Admin shows workspace rows with Open in Editor. Opening a workspace passes only that first-segment subset to the common editor.

The common editor remains platform-agnostic:

  • it receives a list of workspaceFiles,
  • it renders an IDE-style Filetree from path segments,
  • clicking a workflow opens Graph by default,
  • JSON remains available as a tab,
  • graph auto-fit runs after paint,
  • graph side panels open collapsed by default.

Workspace file layout

Exported/imported workspace files mirror canonical paths:

text workspace-root/ customer/ retail/ retail-customer.json case/ review/ kyc-review.json workspace.json

Rules:

  • relative file path must equal $path + ".json",
  • workspace.json is optional metadata,
  • workflow JSON files are authoritative,
  • spawn references are resolved against the imported/exported workspace set.

Source reset and seed contract

Source-only reset remains:

  1. rebuild DB objects from source,
  2. run bootstrap_genesis(),
  3. create fixed namespace registries,
  4. store only system/bootstrap as visible bootstrap,
  5. deploy business/demo workflows through signed process_event events grouped by namespace,
  6. seed demo/customer processes through process_event using canonical paths.

Post-reset checks:

  • get_workflows() contains exactly one bootstrap path: system/bootstrap,
  • no non-system registry stores data.workflows.bootstrap,
  • every deployed workflow path is valid and unique,
  • every deployment event is signed,
  • no $category, no $version: "1.0", no -Vn,
  • every spawn target path resolves.

Non-goals

  • dynamic governed namespace creation,
  • production historical migration,
  • raw SQL workflow mutation,
  • TypeScript workflow semantics,
  • immutable workflow versioning/history semantics.