What we’re building
A workflow that exports data overnight must not be killed half way: a killed export leaves a half-written file. People and AI assistants can both stop runs. So we will not rely on everyone remembering. We will put a supervisor in charge of the workflow: an owner that reviews every command sent to it and can refuse one. A supervisor has two layers. The shell is what Yukta enforces: what the supervisor owns and which commands may pass. The engine is what decides. We use therules engine, which decides with a small JSON document and needs no code and no model.
Save a workflow that takes a while
The workflow starts, waits two minutes in a You should see:With an API key on the server, add
DELAY node, and ends. That gives us time to try stopping it. Create nightly.json:nightly.json
-H "X-API-Key: <your key>" to every call in this tutorial. Saving sessions and supervisors needs an ADMIN key.See the problem: with no supervisor, KILL goes through
Start a run, then kill it:Put the You should see the server accept it. Nobody owns this workflow yet, so the default supervisor carried the command: it lets people act as they always could. The A moment later the run is
executionId from the answer in a variable, then stop the run with mode KILL:Yukta-Via header says who carried it:STOPPED and the work node is CANCELLED. That is the half-written export we wanted to prevent.Write the supervisor
A rules supervisor is a JSON document with a The rule reads: refuse a You should see the saved supervisor in the answer. Settings are checked against the engine, so a misspelt key is a
deny rule. Create no-kill.json:no-kill.json
StopWorkflow command when its mode is KILL, and tell the caller why. Save it:400 that names it, for example settings.rules.Stuck?403means your key is notADMIN.400with asettings.<key>field names the setting the engine did not accept: fix that line and save again.
Give it the session to own
A supervisor reviews only what it owns. An assignment says what: here, every workflow of the session You should see the assignment listed in the answer. One unit has one owner: a save that would give
nightly.nightly to a second supervisor is refused with 409 OWNERSHIP_CONFLICT, naming the other one.Try the same kill again
Start a new run, set You should see the refusal, with your reason in the message, and the supervisor’s name in The run keeps going. Now stop it the way the reason suggests:The same rule holds for every client. A script, the web UI,
EXEC to its id, and send the same command:Yukta-Via (the body is shortened):yukta-cli and an assistant over MCP all send the same command through the same review, and each is refused alike.Stuck? If theKILLstill succeeds, the assignment is missing:Yukta-Via: defaultin the response means nobody owns the workflow. Repeat step 4 and check that the session id insession:nightlyis spelled exactly like the session.
The same two steps with the CLI or an assistant
The same two steps with the CLI or an assistant
With the command-line client:An assistant with an
ADMIN key uses the MCP tools save_supervisor (with type, id and settings) and set_assignments (with supervisorId and assignments). The yukta-workflows skill tells it to ask you before it changes supervision. check_assignment shows what a supervisor would own without saving.What you just did
We made a rule that no caller can skip. We saw the default supervisor let aKILL through, wrote a rules supervisor that refuses it, gave that supervisor the session to own, and saw the refusal carry our reason. The supervisor never ran any of our workflow: it reviewed commands, and the server checked what it could send.
Where to go next
Ask for approval
Next tutorial: a step that waits for a person, and what a supervisor may not answer.
How supervisors work
Shell and engine, ownership, operator access and hierarchy.
Write a rules supervisor
More rules: advise, answer, hold a command for approval.
Rule files
Every field of a rules document.