One canonical definition per term, and the six words that mean two different things.
These are where the confusion actually lives. Everything else is just vocabulary.
| Word | Sense A | Sense B |
|---|---|---|
| step | A template step — the definition, addressed by stepKey. | A ProcessStep — one visit to that step, with its own id. Writes address this. A loop creates several per stepKey. |
| template | The live template in storage, editable. | The snapshot frozen onto a process at start. A run follows this one. |
| role | An app access role — a bundle of app-scoped permissions assigned to declared emails. | A template.roles[] entry — a display name mapped to one permission string. Editor metadata; stores no people. |
| runner | The process runner — the UI at /process/[processId]. | A step runner — applications/main/src/services/*-step-runner.ts, which does an integration's work. |
| completed | The run finished successfully. | The status value, which is also what a failed run is stored as. Failure is only signalled by error. |
| viewer / contributor / editor | Link visibility: none · viewer · contributor. | Assignment role: viewer · editor. contributor and editor both mean "may act"; the words differ by mechanism, not meaning. |
The first one costs the most time. A write addresses the instance, never the key:
PUT /api/process/{processId}/steps/c8f0caa3-b54c-4fe0-ada8-f840a401a462 // ✅ id
PUT /api/process/{processId}/steps/input // ❌ stepKey
process.steps[-1] → { id: "c8f0caa3-…", stepKey: "input" }
process.context → { input: { name: "Test Partner" } } // keyed by stepKey
Context is keyed by step key, so a looping step overwrites its own bucket — while
stepContextAudit keeps every version and process.steps[] keeps one entry per visit.
Assignment — a named person granted access to one process, with role viewer or
editor. Separate from link visibility. → sharing
Context — process.context, where every answer a run collects lands, keyed by step
key. A later step reads an earlier answer as ${step_key.field}.
→ processes
completeExpression — a server-side rule deciding whether a step may be finished.
Distinct from who may edit it, and from mandatory, which is a per-field UI affordance
not enforced on hidden or read-only fields. → expressions
Delivery outcome — what a notify step recorded about its send, stored one level in
(context[stepKey].slackNotify) and read with lib/automation-outcome.ts. Three states:
sent, failed (nothing sent), partial (sent, but somebody it named was not
notified). → step types
Expression — a string evaluated by expression-service.ts. Six slots decide things;
${…} and {{ … }} substitute rather than decide. → expressions
Failure contract — how a step type behaves when it fails: soft (record
the outcome and advance), fail the run (failProcess()), or throw (the worker
catches, logs, and retries forever). Choose it before writing an integration.
→ step types
Frontend profile — see skin.
Impersonation — acting as another user via X-Impersonate-User-Id. Requires
user:impersonate, resolves that user's permissions live, and is the widest grant in the
system. → roles and groups
Instance — see step, sense B.
Organization — distinguish the deployment owner from a participant's Auth0 login affiliation. Neither frontend identity nor selected affiliation assigns process ownership. → roles and groups
Permission — one of the strings like processes:write / database:read, granted by the deployment/app policy and checked in
code at three widths: template, step, field. → permissions
Phase — a label grouping consecutive steps into sections in the editor rail and the runner. Purely presentational; the engine ignores it.
Principal — the app's entire view of a caller: user id, organization, permissions. No roles, no groups, no profile. → roles and groups
Process — one run of a template, carrying its own context, audit trail, and a frozen copy of the template. → processes
Record — a derived, never-stored summary of a finished run, computed on read. Adds a
failed outcome the platform itself cannot store.
→ records
run bucket — the reserved context key holding runInputs collected on the start
screen, before the process existed. Referenced as run.<key>.
Seeding — writing repo templates into storage. Fills gaps only; overwriting requires
--force. → manage templates
Skin — a frontend profile selected by NEXT_PUBLIC_FRONTEND_ID, controlling
branding, navigation, and optionally the homepage. Never an access boundary.
→ whitelabel
Snapshot — the expanded copy of a template taken at startProcess and never
refreshed. Editing a template does not change runs in flight.
→ templates
stepContextAudit — the append-only trail of every context write, carrying actor,
timestamp, step key, and the values. Never overwritten, never compacted. userId: "system" marks automation.
Subroutine — a reusable group of fields defined under applications/main/src/templates/shared/,
expanded into real leaf fields at process start. Anything comparing two templates must
expand both sides first. → field types
Tick — one pass of the worker's 1000 ms loop: list every process, filter to
running, execute the current step of each.
→ the process engine
Template — the recipe: firstStepKey, steps[], permissions[]. Lives in storage,
not the repo. → templates
View control — a read-only field rendering resolved defaultValue text instead of an
input. There is no separate display field type; resultViewControls[] does the same job
on the completion screen.
Worker — the separate process started by npm run job:step that advances every step
type except input. Exactly one per database.
→ the process engine