The LLM-workflow runtime (executor B)¶
Executor B runs an intent as an in-band model workflow: a Hub-hosted Claude Messages-API loop whose every tool call passes the same gate and can escalate to you. It is the alternative to spawning a Commander, for work that is "read, reason, act" rather than "get a machine and build."
The defining property is in-band by construction: because the Hub itself makes every model call and dispatches every tool, it sees and controls every step. There is no external session to observe through a side channel — the loop is the Hub.
Status
The underlying model tool-loop, the Messages-API client, cost accounting, the cron/event triggers, and the SSRF-safe egress path are live in the platform. The workflow definition, the run executor, the universal HTTP connector, and the A/B selector described here are merged on main but dark behind a default-OFF flag — dev-safe, and not yet activated in production.
The worked example¶
"Every morning, summarize the newsfeed list and post it to my site."
A saved workflow with a schedule trigger: the model reads the list (a fetch action),
summarizes it (a model step), and posts it (an HTTP action). Each action is gated
allowed / needs-approval / denied. If the post is gated needs-approval, it
escalates to you and resumes on approval. No Commander is ever spawned — a
"post to my site" job needs only the model plus the gate.
The runtime loop¶
At heart the runtime is a bounded model-plus-tools loop:
flowchart TD
T[Trigger fires] --> R[Resolve model + build system prompt<br/>role · injected knowledge · trigger context]
R --> L[Build tools = the workflow's allowed actions]
L --> C[model call]
C --> S{stop reason}
S -->|tool_use| G{{gate each action}}
G -->|allow| DISP[dispatch → tool_result]
G -->|deny| DR[model-readable denial → tool_result]
G -->|needs approval| PAUSE[pause + escalate]
PAUSE -->|approved| DISP
DISP --> C
DR --> C
S -->|stop| OUT[emit result to destination]
Each turn: build the request with the allowed tools, call the model, and for each
tool-use block the model emits, gate the action. On allow, dispatch it and feed
the result back. On needs-approval, pause the run and escalate. On deny, feed a
model-readable denial back as the tool result and let the loop continue in a degraded
state — it never bypasses. The loop is bounded by a maximum iteration count and a
per-run cost budget.
What a workflow is¶
A workflow is a saved, per-user definition — one row per saved workflow, owned per user (the tenancy key lives here). Its fields:
- model — an explicit model or a role/task-type the router resolves, plus a thinking level.
- role / prompt — the system prompt and persona for the loop.
- allowed_actions — the action allow-set: an explicit list of tool names, integration verbs, and named HTTP-connector actions the workflow may call. Default-deny: only listed actions are offered to the model as tools, and each is independently gated at call time.
- trigger — one of
schedule(cron),event(a bus predicate), oron_demand. - output / destination — where the result goes: a result message, a report, an alert push, or a named HTTP destination.
- gates — the per-workflow, per-action policy, composed with the estate's gate model.
- budget — a per-run cost ceiling (and optionally per-day).
- cred_refs — references to the credentials the workflow may use, never inline secrets (see Credential scoping).
Each execution is a separate run record, moving through pending → running →
awaiting_approval → done / failed / denied, stamped with trigger provenance, the
accumulated token usage and cost, and a transcript pointer.
The action vocabulary¶
A workflow's tools come from one uniform vocabulary so that everything is "configured the same way":
- Hub tool surface — the existing set of agent-action tools.
- Integration verbs — per-integration outbound connectors with encrypted credentials.
- A universal HTTP/webhook action — a typed
http_request{method, url, headers, body}for "post to my site" / "curl," behind SSRF protection and the gate.
Spawn is optional: if an allowed action happens to be a spawn action, the loop dispatches it exactly like any other action, through the same gate — and only then is a Commander spun up. Executors A and B are not mutually exclusive at the action level; the selector only picks the top-level executor.
Safety properties¶
The runtime inherits the platform's invariants and adds none weaker:
- Default-deny at every action — only allow-set actions are offered; each is independently gated; anything unlisted is denied.
- The workflow model never self-approves — it can propose a gated or irreversible action, never approve it. Prod deploys and external publishes always pause for you.
- Fail-closed — an approval timeout defaults to deny; a gate or resolution fault denies; a denied action degrades the run, it never bypasses.
- Verified identity, injected — the action's credential is injected server-side over the model-supplied params; the model never sees a raw secret (the confused-deputy defense).
- Bounded — per-run cost and budget caps, bounded loop iterations, a per-turn dispatch budget, and a timeout.
- SSRF-safe egress — every external action is pinned through resolved-IP classification with DNS-rebind defense.
- Audited and observable in-band — every action, gate decision, and approval is on the tamper-evident audit chain, and the whole run is visible in the Hub.
- Irreversible ⇒ human — prod, irreversible, or external-publish actions always escalate to you.
Provider note¶
Tool-use workflows run on the Claude Messages API, which is where the multi-turn tool loop lives. Non-tool "summarize" steps can use provider-flexible completion; a multi-provider tool-use bridge is a larger, separate effort and is out of scope for the first version.