Issue #3624248: Let a caller name the run it starts over the API, and a subprocess step name its child

A run carries a correlation key, the business reference an external event resolves it by, and the HTTP API could read it back and never set it. A run started over the API had an empty key for its whole life, and the runs that most need one are exactly those: a remote_subprocess child runs on the other site, which is where an event about it arrives, and nothing over there could name it.

startProcess() takes the key, the start endpoint validates and forwards it, and openapi.yaml describes it on the request as it already did on the response.

Refused over 255 characters rather than clamped to the column the engine clamps to. A key cut to fit is a key the caller will never find the run by: the event arrives later carrying the whole thing, matches nothing, and the run waits for something that already happened. Refused at the start, the caller can send a shorter name instead. The published limit is read off the client's own constant by a test, so moving one without the other is the failure.

Not the idempotency key, whatever the two names suggest. That one answers whether this request has already been served: read once, before anything is created, resolving to at most one run. This one answers which live run an event is about: read for as long as the run is running, and several runs may legitimately share it. Said so in both docblocks and in the published document, because a caller holding both will otherwise reach for the wrong one.

The wire version moves to 2, its minimum staying 1. A site one version behind ignores the new field, so the start succeeds over there and the run it makes cannot be found by the key the caller chose: the quietly absent field the version check exists to turn into an answer. Everything version 1 asks for is still here, so an older caller is still worked with, which the handshake test now asserts rather than implies.

Tests: the key reaches the run and the engine's correlation lookup finds it, an empty key names nothing, an over-long one is refused and makes no run, the endpoint answers 400 for a non-string and 422 for an over-long key, the remote client sends both names and neither when there are none, and the document publishes the limit the client enforces.

A second finding, folded in rather than filed. Auditing this found the same defect on the field beside it: the document names 128 characters for the idempotency_key and nothing enforced it. That key is written from inside the start, after the run is created, so a longer one failed the insert in there. Probed against MySQL, a 200-character key was answered 500 with no run made, for a request whose only fault the caller could have been told about; where a database stores it cut short instead, two attempts whose keys differ only past the cut become one attempt and the second caller is handed the first one's run. Both names a start carries are now checked in one place, and the published bound for each is read off the client's own constant by a test.

One contract statement the audit made explicit. A repeat is decided before anything is created, so the second ask makes no run and there is nothing for a correlation key to land on: a caller that corrects the name on a retry is still holding the run the first ask named. That is the right behaviour and it was the unwritten one, and the other reading, that the retry renamed it, is the one a caller would act on. It is now in the contract and pinned by a test, which also stops a later reading of "apply what the caller sent" from being mistaken for a fix.

Note also what this does not do: the remote_subprocess node still has nowhere to take a correlation key from, so a child it launches carries none and nothing can give it one afterwards. The docs say so rather than leaving the reader to infer it from the section above. Giving that node a place to name its children is a design question of its own (a literal, a variable to read, the modeler round trip), so it is not folded in here.

Edited by Frank Mably

Merge request reports

Loading