FlowDrop Workflow Specification 1.0-draft

An interrupt is published as 24 keys, every one always present

One shape, from every endpoint that publishes an interrupt. A consumer reads a key rather than testing whether it is there, because an absent value is present and null.

The rule

Normative: this is the rule
  1. Every endpoint that publishes an interrupt publishes the same entry: 24 keys, uniformly camelCase, in this order: id, type, status, message, nodeId, workflowId, pipelineId, sessionId, schema, options, context, defaultValue, responseData, createdAt, expiresAt, scheduledAt, resolvedAt, resolvedBy, direction, jobId, targetPipelineId, initiatorUid, reason, linkedInterruptId.
  2. id is the interrupt's UUID; type, status and direction are the enumerated values (STORE-11); and all four timestamps are ISO-8601 strings or null, never integers.
  3. Every optional member is present and null rather than omitted.
  4. An endpoint listing interrupts answers a JSON array, and must still answer an array after access filtering has removed entries.

What it means

Every endpoint that publishes an interrupt publishes the same 24 keys, in the same order, whichever door answered. A consumer that reads this shape once can read it everywhere; a consumer that has to special-case one endpoint's fields is reading a contract that was never actually shared.

The clause worth catching is presence, not content: an unset member is published as the key with a null value, never left out of the object. A consumer that checks whether a key exists, instead of reading its value, would read an unset member as though the endpoint had a different shape than the one that set it — the two are indistinguishable unless absence is never allowed to mean anything.

Example

The interrupt entry's key set, in order
["id", "type", "status", "message", "nodeId", "workflowId", "pipelineId", "sessionId", "schema", "options", "context", "defaultValue", "responseData", "createdAt", "expiresAt", "scheduledAt", "resolvedAt", "resolvedBy", "direction", "jobId", "targetPipelineId", "initiatorUid", "reason", "linkedInterruptId"]
One interrupt's unset membersnull
{"schema": null, "options": null, "context": null, "expiresAt": null, "scheduledAt": null, "resolvedAt": null, "resolvedBy": null}

Nothing here is omitted; each of these keys sits in its place in the 24-key entry above, carrying null rather than being left out.

Rule identifiers are permanent and are never renumbered. Each implementation publishes its own standing against these rules; this specification does not.spec 1.0-draft · INT-22 · changed in spec 1.0