Skip to main content
Use this when the decision lives in another system or needs open-ended judgement: a script that checks machine load, a service with its own rules, an AI agent. The http engine is the way an application or agent becomes a supervisor. The server stays in charge: it checks every directive before it has any effect. Prerequisites: a server on http://localhost:9858 and a session to supervise (steer, from Control a run). Add -H "X-API-Key: $YUKTA_API_KEY" if your server has keys; creating the supervisor and its credential needs ADMIN.

Steps

1

Save the supervisor with its limits

The supervisor is the shell: what it owns and what it may send. The program decides inside those limits. This one may pause and resume runs, and may do so on its own initiative, up to 20 times a minute. Save as cpu-guard.json:
cpu-guard.json
A command a supervisor sends with no triggering signal (a tick, or its own idea) is initiative: it needs a reason, an entry in initiative and stays under maxInitiativePerMinute (default 10). Optional settings: url (Yukta posts each signal there), headers, secretHeaders (shown as ***), timeoutMs (3000, at most 10000), maxConcurrent (4, at most 32).
2

Issue its credential

The token is returned once with an expiresAt. Issuing again rotates it (the old one stops working at once); DELETE .../credential or yukta-cli supervisors credential revoke cpu-guard revokes it. Add &allowedAddresses=10.0.0.5 to tie it to source addresses. It works on /api/agent/v1 only, and no person’s API key works there. Through MCP, create_credential returns the token, which then passes through the model: prefer the UI or the CLI.
3

Run your program

The quickest way is yukta-cli supervisors agent: it streams the signals to a program’s standard input, one JSON line each, and sends every JSON line the program prints as a directive. A shell script is enough (this is examples/18-supervisor-agents/cpu_guard.sh, trimmed):
cpu_guard.sh
A directive has a unique key (applied once), a cause, a reason, an optional ifStatus (dropped as precondition-failed if the run is not in that status) and the command. "target":"held" means the runs this supervisor paused. Other targets: execution:<id>, workflow:<id>, owned.running; each is expanded to at most 200 runs, each applied and audited on its own.Prefer your own client? Python and Go versions are in example 18. The calls are plain HTTP with Authorization: Bearer <token> on /api/agent/v1:An AI agent can use the same operations as MCP tools at POST /api/agent/v1/mcp.
4

Make the decisions auditable

Give the program a clear reason for every directive: it is recorded in the control audit next to the supervisor’s id. If you run a model, treat run logs, prompts and context as untrusted data, and keep allowedCommands and initiative as narrow as the job allows.

Verify it worked

Start a run in steer, then:
When the program sends a directive, a decision appears with an outcome. applied means the command ran. A command outside allowedCommands is forbidden, one for a run the supervisor does not own is not-owned, an initiative without a reason or beyond the per-minute limit is initiative-not-allowed or rate-limited, and a failed ifStatus is precondition-failed. Lower LIMIT (for example LIMIT=0.01) to force a pause, and watch the run’s status. Check the credential with yukta-cli supervisors credential show cpu-guard: it shows when it was issued and last used, never the secret.

Variations

  • Limits per credential. yukta.agent.requests-per-minute (600), yukta.agent.failures-per-minute (20 wrong credentials per source address), yukta.agent.max-body-bytes (65536), two open streams, and 100 reviews waiting at once.
  • Have Yukta call you. With url set, Yukta posts each signal as {"cursor","kind","signal"} (through the egress rules; private addresses are refused unless listed; no redirects). The reply is not read, and a failed post is not retried: read GET /signals?after=<cursor> to catch up. Decisions always come back over /api/agent/v1.
  • A program on the server instead. The process engine runs an executable from yukta.process.allowed-commands with an empty environment, one JSON line in and out: Supervisor engines.
  • Answer input requests. Give the supervisor canAnswer: true and maxRisk; HIGH is people only: Route input requests.
  • Slow consumers. A supervisor that falls behind receives an EventsMissed signal; read GET /inputs and the run list to catch up.