Agent Runner Operations
Status: Active
Purpose: Teach FlowState agent harnesses how to operate the co-resident flowstate-runner Rust daemon inside their agent container
Scope: Agent sidecars that run the Rust process execution engine, regardless of chat or coding harness
Trigger: Agent needs to monitor or control process executions assigned to its team member ID
Input: Running agent container with FLOWSTATE_AGENT_ID, FlowState CLI, and flowstate-runner
Output: Runner status understood, assigned process executions advanced or safely paused/cancelled, and failures diagnosed
Overview
FlowState agents do not manually walk process steps unless the runner is unavailable or a step explicitly asks for agent reasoning. The Rust runner is the primary process driver. Agents monitor the runner, create or assign work in FlowState, trigger scans/resumes, and handle the small number of inference-heavy agent-task steps only when the process engine delegates them.
Verify Scope -> Check Runner -> List Executions -> Inspect Work
(0) (1) (2) (3)
|
v
Act on Execution <- Diagnose Failure <- Resume/Scan <- Observe Pause
(6) (5) (4) (4)
Architecture
Each agent sidecar runs two long-lived services under s6:
| Service |
Purpose |
| agent gateway |
Chat/tool harness process, such as OpenClaw, Hermes, or another compatible runtime. The agent uses this process to think, answer, and call tools. |
flowstate-runner |
Rust daemon that scans FlowState, creates processexecutions, resumes paused executions, and executes steps. |
The runner is scoped by environment:
| Env var |
Required |
Purpose |
FLOWSTATE_AGENT_ID |
Yes |
Team member ID this runner is allowed to execute for. |
FLOWSTATE_AGENT_NAME |
No |
Human-readable agent name used in logs and worker heartbeat metadata. |
RUNNER_CONTROL_TOKEN |
Yes for control API |
Bearer token used by flowstate runner ...; generated into /run/runner.token. |
RUNNER_CONTROL_URL |
No |
Control API URL. Defaults to http://localhost:9090. |
RUNNER_MAX_CONCURRENT |
No |
Concurrent execution limit. Defaults to 5. |
The runner enforces scope in three places:
- Scanner looks for entity-triggered processes assigned to
metadata.assignedAgent = FLOWSTATE_AGENT_ID.
- Resumer looks for paused executions with
variables.assignedAgent = FLOWSTATE_AGENT_ID.
- Run guard refuses to execute a record assigned to a different team member.
Step 0: Verify Container Scope
Who: FlowState agent
Pause: No
Actions
- Read the configured agent identity:
printf 'FLOWSTATE_AGENT_ID=%s\nFLOWSTATE_AGENT_NAME=%s\n' "$FLOWSTATE_AGENT_ID" "$FLOWSTATE_AGENT_NAME"
- Confirm runner tools exist:
command -v flowstate
command -v flowstate-runner
- Confirm the control token is available to the agent runtime user:
test -s /run/runner.token && echo "runner token present"
- If
RUNNER_CONTROL_TOKEN is not exported in the shell, export it from the token file for this session:export RUNNER_CONTROL_TOKEN="$(cat /run/runner.token)"
export RUNNER_CONTROL_URL="${RUNNER_CONTROL_URL:-http://localhost:9090}"
Done when
FLOWSTATE_AGENT_ID is non-empty
flowstate and flowstate-runner are on PATH
RUNNER_CONTROL_TOKEN is available for CLI control commands
Step 1: Check Runner Health
Who: FlowState agent
Pause: No
Actions
- Use the FlowState CLI first:
flowstate runner status --format json
- Confirm the response includes:
status: "ok"
agentId matching FLOWSTATE_AGENT_ID
runningExecutions, possibly empty
lastActivityAt, if the runner has found work
- If the CLI fails, check the raw health endpoint:
curl -fsS http://localhost:9090/health | jq .
- If health fails, inspect s6 service state and recent logs:
s6-rc -a list | grep flowstate-runner
s6-svstat /run/service/flowstate-runner
tail -200 /run/service/flowstate-runner/log/current 2>/dev/null || true
Done when
- Runner health is reachable
- Agent scope is verified
- Any active execution IDs are known
Step 2: List Assigned Executions
Who: FlowState agent
Pause: No
Actions
- List executions controlled by this runner:
flowstate runner ls
- For machine-readable inspection:
flowstate runner ls --format json
- Filter by status when triaging:
flowstate runner ls --status running
flowstate runner ls --status paused
flowstate runner ls --status failed
flowstate runner ls --status completed --limit 20
- Treat an empty list as "no scoped executions visible", not as failure. Trigger a scan if new assigned work should exist.
Done when
- The agent knows which scoped executions exist and which need attention
Step 3: Inspect an Execution
Who: FlowState agent
Pause: No
Actions
- Show the execution:
flowstate runner show <execution_id> --format json
- Inspect:
processId
status
currentStepId
variables.assignedAgent
variables.entityId, entityType, entityCollection
stepHistory
error
- Confirm
variables.assignedAgent matches FLOWSTATE_AGENT_ID. If it does not, do not try to bypass the guard.
- If a process or step needs direct DB inspection, use FlowState collection tools with real IDs from
.flowstate/config.json; never guess IDs.
Done when
- Current process, step, entity, pause/failure reason, and ownership are understood
Step 4: Trigger Scan or Resume
Who: FlowState agent
Pause: No
Actions
- Trigger a scan when an entity was newly assigned or tagged:
flowstate runner scan
This schedules work and returns quickly. Check flowstate runner ls afterwards.
- Trigger a resume cycle when approvals, human-task responses, or pause conditions were satisfied:
flowstate runner resume
- Force a single paused execution back to pending only when the pause condition is genuinely satisfied or the operator intentionally wants to retry:
flowstate runner resume <execution_id>
Done when
- New eligible work has a
processexecutions row, or paused eligible work has moved to pending/running
Step 5: Diagnose Stalls and Failures
Who: FlowState agent
Pause: No
Actions
- For a paused execution, inspect the pause reason:
flowstate runner show <execution_id> --format json | jq '.metadata._pause_reason, .currentStepId, .variables'
- If waiting on an approval, query the approval record shown in variables or pause metadata and look for
status, response, and comments.
- For a failed execution, inspect:
flowstate runner show <execution_id> --format json | jq '.error, .stepHistory[-5:]'
- Try runner logs, but know the current
/executions/:id/logs endpoint may return a placeholder until OBS proxying is fully wired:flowstate runner logs <execution_id>
- Fall back to container logs when needed:
ps -ef | grep flowstate-runner
s6-svstat /run/service/flowstate-runner
Done when
- The agent can state whether the execution is waiting, failed due to a step error, mis-scoped, or blocked by runner health/configuration
Step 6: Pause, Cancel, or Restart Safely
Who: FlowState agent
Pause: Maybe
Actions
- Pause only when work must stop without losing persisted state:
flowstate runner pause <execution_id> --reason "manual: <short reason>"
- Cancel only when the execution should be marked failed and should not continue:
flowstate runner cancel <execution_id> --reason "manual: <short reason>"
- Restart the runner service only for runner process health issues, not normal paused work:
s6-svc -r /run/service/flowstate-runner
- After any pause/cancel/restart, re-check:
flowstate runner status --format json
flowstate runner ls --format json
Done when
- The execution state in FlowState matches the intended operator action
- The runner is healthy after service-level intervention
Creating Runner-Eligible Work
Agents create process-driven work by creating or updating FlowState entities so scanner triggers can match them.
Required entity metadata for agent-scoped process triggers:
{
"metadata": {
"assignedAgent": "<FLOWSTATE_AGENT_ID or target team member id>"
},
"tags": ["brainstorm"]
}
Guidelines:
- Set
metadata.assignedAgent to the target agent team member ID before triggering process scans.
- Include the process trigger tag or status expected by the registered process, such as
brainstorm.
- For CEO-to-CTO work, the CEO-created entity should have
metadata.assignedAgent set to the CTO team member ID and any approver variables set to the CEO team member ID when the process supports peer approval routing.
- After creating or updating the entity, the target agent runs
flowstate runner scan.
Manual Execution Fallback
Manual MCP process execution is the fallback path, not the default.
Use flowstate-process-execution only when:
flowstate-runner is unavailable and cannot be restarted
- A process definition is being debugged before runner registration
- The runner fails on a step and you need to reproduce the step by hand
- A human explicitly asks for a manual process walkthrough
When using the fallback, record what was done in the execution, entity discussion, or approval trail so the runner and future agents have durable context.
Error Handling
| Situation |
Action |
FLOWSTATE_AGENT_ID missing |
Do not run unscoped. Fix container/orchestrator env and restart the sidecar. |
flowstate runner status returns 401 |
Export RUNNER_CONTROL_TOKEN="$(cat /run/runner.token)" and retry. |
flowstate runner status returns 503 |
Runner booted without RUNNER_CONTROL_TOKEN; check runner-token s6 service and restart flowstate-runner. |
flowstate runner show returns 403 |
Execution belongs to another agent; stop and route to the assigned agent. |
| New work not discovered |
Confirm entity trigger fields, especially metadata.assignedAgent, status, tags, orgId, and workspaceId; then run flowstate runner scan. |
| Execution stuck paused |
Inspect _pause_reason, approvals, and current step; resume only after the condition is satisfied. |
| Runner repeatedly exits idle |
Check IDLE_TIMEOUT_SECS; durable/manual agent containers usually set IDLE_TIMEOUT_SECS=0. |
Command Reference
| Command |
Purpose |
flowstate runner status --format json |
Health, agent scope, running execution IDs. |
flowstate runner ls [--status <status>] [--format json] |
List scoped process executions. |
flowstate runner show <id> --format json |
Inspect one execution. |
flowstate runner scan |
Schedule immediate scanner pass. |
flowstate runner resume |
Schedule immediate resumer pass. |
flowstate runner resume <id> |
Move one scoped execution back to pending. |
flowstate runner pause <id> --reason "..." |
Mark one scoped execution paused. |
flowstate runner cancel <id> --reason "..." |
Mark one scoped execution failed. |
flowstate runner logs <id> |
Execution log endpoint; may be placeholder until OBS proxy is wired. |
flowstate-runner --project-root <agent_home> scan |
Direct binary scanner, mostly for debugging. Current OpenClaw sidecars use /home/openclaw. |
flowstate-runner --project-root <agent_home> resume |
Direct binary resumer, mostly for debugging. Current OpenClaw sidecars use /home/openclaw. |
flowstate-runner --project-root <agent_home> run <id> |
Direct binary execution, guarded by agent scope. Current OpenClaw sidecars use /home/openclaw. |
Safety Rules
- Do not clear or forge
variables.assignedAgent to bypass scope.
- Do not operate on another agent's execution from this container.
- Do not mutate
processexecutions directly. Use runner commands; if a repair path is missing, record a tool-surface gap before changing process execution state.
- Prefer scan/resume over direct
flowstate-runner run <id> during normal operations.
- Keep inference work inside
agent-task steps or explicit human requests; use CLI/MCP commands for deterministic process actions.
Created: 2026-05-24
Source: epic-digital-im/epic-flowstate-skills — distributed by TomeVault.
1---2name: flowstate-agent-runner-operations3description: Use when any FlowState agent harness is running inside an agent sidecar and needs to inspect, monitor, start, stop, resume, cancel, or debug the Rust process runner - provides the in-container runner control workflow and safety rules4---56# Agent Runner Operations78**Status:** Active9**Purpose:** Teach FlowState agent harnesses how to operate the co-resident `flowstate-runner` Rust daemon inside their agent container10**Scope:** Agent sidecars that run the Rust process execution engine, regardless of chat or coding harness11**Trigger:** Agent needs to monitor or control process executions assigned to its team member ID12**Input:** Running agent container with `FLOWSTATE_AGENT_ID`, FlowState CLI, and `flowstate-runner`13**Output:** Runner status understood, assigned process executions advanced or safely paused/cancelled, and failures diagnosed1415---1617## Overview1819FlowState agents do not manually walk process steps unless the runner is unavailable or a step explicitly asks for agent reasoning. The Rust runner is the primary process driver. Agents monitor the runner, create or assign work in FlowState, trigger scans/resumes, and handle the small number of inference-heavy `agent-task` steps only when the process engine delegates them.2021```22Verify Scope -> Check Runner -> List Executions -> Inspect Work23 (0) (1) (2) (3)24 |25 v26Act on Execution <- Diagnose Failure <- Resume/Scan <- Observe Pause27 (6) (5) (4) (4)28```2930---3132## Architecture3334Each agent sidecar runs two long-lived services under s6:3536| Service | Purpose |37| ------- | ------- |38| agent gateway | Chat/tool harness process, such as OpenClaw, Hermes, or another compatible runtime. The agent uses this process to think, answer, and call tools. |39| `flowstate-runner` | Rust daemon that scans FlowState, creates `processexecutions`, resumes paused executions, and executes steps. |4041The runner is scoped by environment:4243| Env var | Required | Purpose |44| ------- | -------- | ------- |45| `FLOWSTATE_AGENT_ID` | Yes | Team member ID this runner is allowed to execute for. |46| `FLOWSTATE_AGENT_NAME` | No | Human-readable agent name used in logs and worker heartbeat metadata. |47| `RUNNER_CONTROL_TOKEN` | Yes for control API | Bearer token used by `flowstate runner ...`; generated into `/run/runner.token`. |48| `RUNNER_CONTROL_URL` | No | Control API URL. Defaults to `http://localhost:9090`. |49| `RUNNER_MAX_CONCURRENT` | No | Concurrent execution limit. Defaults to `5`. |5051The runner enforces scope in three places:52531. Scanner looks for entity-triggered processes assigned to `metadata.assignedAgent = FLOWSTATE_AGENT_ID`.542. Resumer looks for paused executions with `variables.assignedAgent = FLOWSTATE_AGENT_ID`.553. Run guard refuses to execute a record assigned to a different team member.5657---5859## Step 0: Verify Container Scope6061**Who:** FlowState agent62**Pause:** No6364### Actions65661. Read the configured agent identity:67 ```bash68 printf 'FLOWSTATE_AGENT_ID=%s\nFLOWSTATE_AGENT_NAME=%s\n' "$FLOWSTATE_AGENT_ID" "$FLOWSTATE_AGENT_NAME"69 ```702. Confirm runner tools exist:71 ```bash72 command -v flowstate73 command -v flowstate-runner74 ```753. Confirm the control token is available to the agent runtime user:76 ```bash77 test -s /run/runner.token && echo "runner token present"78 ```794. If `RUNNER_CONTROL_TOKEN` is not exported in the shell, export it from the token file for this session:80 ```bash81 export RUNNER_CONTROL_TOKEN="$(cat /run/runner.token)"82 export RUNNER_CONTROL_URL="${RUNNER_CONTROL_URL:-http://localhost:9090}"83 ```8485### Done when8687- `FLOWSTATE_AGENT_ID` is non-empty88- `flowstate` and `flowstate-runner` are on `PATH`89- `RUNNER_CONTROL_TOKEN` is available for CLI control commands9091---9293## Step 1: Check Runner Health9495**Who:** FlowState agent96**Pause:** No9798### Actions991001. Use the FlowState CLI first:101 ```bash102 flowstate runner status --format json103 ```1042. Confirm the response includes:105 - `status: "ok"`106 - `agentId` matching `FLOWSTATE_AGENT_ID`107 - `runningExecutions`, possibly empty108 - `lastActivityAt`, if the runner has found work1093. If the CLI fails, check the raw health endpoint:110 ```bash111 curl -fsS http://localhost:9090/health | jq .112 ```1134. If health fails, inspect s6 service state and recent logs:114 ```bash115 s6-rc -a list | grep flowstate-runner116 s6-svstat /run/service/flowstate-runner117 tail -200 /run/service/flowstate-runner/log/current 2>/dev/null || true118 ```119120### Done when121122- Runner health is reachable123- Agent scope is verified124- Any active execution IDs are known125126---127128## Step 2: List Assigned Executions129130**Who:** FlowState agent131**Pause:** No132133### Actions1341351. List executions controlled by this runner:136 ```bash137 flowstate runner ls138 ```1392. For machine-readable inspection:140 ```bash141 flowstate runner ls --format json142 ```1433. Filter by status when triaging:144 ```bash145 flowstate runner ls --status running146 flowstate runner ls --status paused147 flowstate runner ls --status failed148 flowstate runner ls --status completed --limit 20149 ```1504. Treat an empty list as "no scoped executions visible", not as failure. Trigger a scan if new assigned work should exist.151152### Done when153154- The agent knows which scoped executions exist and which need attention155156---157158## Step 3: Inspect an Execution159160**Who:** FlowState agent161**Pause:** No162163### Actions1641651. Show the execution:166 ```bash167 flowstate runner show <execution_id> --format json168 ```1692. Inspect:170 - `processId`171 - `status`172 - `currentStepId`173 - `variables.assignedAgent`174 - `variables.entityId`, `entityType`, `entityCollection`175 - `stepHistory`176 - `error`1773. Confirm `variables.assignedAgent` matches `FLOWSTATE_AGENT_ID`. If it does not, do not try to bypass the guard.1784. If a process or step needs direct DB inspection, use FlowState collection tools with real IDs from `.flowstate/config.json`; never guess IDs.179180### Done when181182- Current process, step, entity, pause/failure reason, and ownership are understood183184---185186## Step 4: Trigger Scan or Resume187188**Who:** FlowState agent189**Pause:** No190191### Actions1921931. Trigger a scan when an entity was newly assigned or tagged:194 ```bash195 flowstate runner scan196 ```197 This schedules work and returns quickly. Check `flowstate runner ls` afterwards.1982. Trigger a resume cycle when approvals, human-task responses, or pause conditions were satisfied:199 ```bash200 flowstate runner resume201 ```2023. Force a single paused execution back to pending only when the pause condition is genuinely satisfied or the operator intentionally wants to retry:203 ```bash204 flowstate runner resume <execution_id>205 ```206207### Done when208209- New eligible work has a `processexecutions` row, or paused eligible work has moved to `pending`/`running`210211---212213## Step 5: Diagnose Stalls and Failures214215**Who:** FlowState agent216**Pause:** No217218### Actions2192201. For a paused execution, inspect the pause reason:221 ```bash222 flowstate runner show <execution_id> --format json | jq '.metadata._pause_reason, .currentStepId, .variables'223 ```2242. If waiting on an approval, query the approval record shown in variables or pause metadata and look for `status`, `response`, and `comments`.2253. For a failed execution, inspect:226 ```bash227 flowstate runner show <execution_id> --format json | jq '.error, .stepHistory[-5:]'228 ```2294. Try runner logs, but know the current `/executions/:id/logs` endpoint may return a placeholder until OBS proxying is fully wired:230 ```bash231 flowstate runner logs <execution_id>232 ```2335. Fall back to container logs when needed:234 ```bash235 ps -ef | grep flowstate-runner236 s6-svstat /run/service/flowstate-runner237 ```238239### Done when240241- The agent can state whether the execution is waiting, failed due to a step error, mis-scoped, or blocked by runner health/configuration242243---244245## Step 6: Pause, Cancel, or Restart Safely246247**Who:** FlowState agent248**Pause:** Maybe249250### Actions2512521. Pause only when work must stop without losing persisted state:253 ```bash254 flowstate runner pause <execution_id> --reason "manual: <short reason>"255 ```2562. Cancel only when the execution should be marked failed and should not continue:257 ```bash258 flowstate runner cancel <execution_id> --reason "manual: <short reason>"259 ```2603. Restart the runner service only for runner process health issues, not normal paused work:261 ```bash262 s6-svc -r /run/service/flowstate-runner263 ```2644. After any pause/cancel/restart, re-check:265 ```bash266 flowstate runner status --format json267 flowstate runner ls --format json268 ```269270### Done when271272- The execution state in FlowState matches the intended operator action273- The runner is healthy after service-level intervention274275---276277## Creating Runner-Eligible Work278279Agents create process-driven work by creating or updating FlowState entities so scanner triggers can match them.280281Required entity metadata for agent-scoped process triggers:282283```json284{285 "metadata": {286 "assignedAgent": "<FLOWSTATE_AGENT_ID or target team member id>"287 },288 "tags": ["brainstorm"]289}290```291292Guidelines:293294- Set `metadata.assignedAgent` to the target agent team member ID before triggering process scans.295- Include the process trigger tag or status expected by the registered process, such as `brainstorm`.296- For CEO-to-CTO work, the CEO-created entity should have `metadata.assignedAgent` set to the CTO team member ID and any approver variables set to the CEO team member ID when the process supports peer approval routing.297- After creating or updating the entity, the target agent runs `flowstate runner scan`.298299---300301## Manual Execution Fallback302303Manual MCP process execution is the fallback path, not the default.304305Use `flowstate-process-execution` only when:306307- `flowstate-runner` is unavailable and cannot be restarted308- A process definition is being debugged before runner registration309- The runner fails on a step and you need to reproduce the step by hand310- A human explicitly asks for a manual process walkthrough311312When using the fallback, record what was done in the execution, entity discussion, or approval trail so the runner and future agents have durable context.313314---315316## Error Handling317318| Situation | Action |319| --------- | ------ |320| `FLOWSTATE_AGENT_ID` missing | Do not run unscoped. Fix container/orchestrator env and restart the sidecar. |321| `flowstate runner status` returns 401 | Export `RUNNER_CONTROL_TOKEN="$(cat /run/runner.token)"` and retry. |322| `flowstate runner status` returns 503 | Runner booted without `RUNNER_CONTROL_TOKEN`; check `runner-token` s6 service and restart `flowstate-runner`. |323| `flowstate runner show` returns 403 | Execution belongs to another agent; stop and route to the assigned agent. |324| New work not discovered | Confirm entity trigger fields, especially `metadata.assignedAgent`, status, tags, `orgId`, and `workspaceId`; then run `flowstate runner scan`. |325| Execution stuck paused | Inspect `_pause_reason`, approvals, and current step; resume only after the condition is satisfied. |326| Runner repeatedly exits idle | Check `IDLE_TIMEOUT_SECS`; durable/manual agent containers usually set `IDLE_TIMEOUT_SECS=0`. |327328---329330## Command Reference331332| Command | Purpose |333| ------- | ------- |334| `flowstate runner status --format json` | Health, agent scope, running execution IDs. |335| `flowstate runner ls [--status <status>] [--format json]` | List scoped process executions. |336| `flowstate runner show <id> --format json` | Inspect one execution. |337| `flowstate runner scan` | Schedule immediate scanner pass. |338| `flowstate runner resume` | Schedule immediate resumer pass. |339| `flowstate runner resume <id>` | Move one scoped execution back to pending. |340| `flowstate runner pause <id> --reason "..."` | Mark one scoped execution paused. |341| `flowstate runner cancel <id> --reason "..."` | Mark one scoped execution failed. |342| `flowstate runner logs <id>` | Execution log endpoint; may be placeholder until OBS proxy is wired. |343| `flowstate-runner --project-root <agent_home> scan` | Direct binary scanner, mostly for debugging. Current OpenClaw sidecars use `/home/openclaw`. |344| `flowstate-runner --project-root <agent_home> resume` | Direct binary resumer, mostly for debugging. Current OpenClaw sidecars use `/home/openclaw`. |345| `flowstate-runner --project-root <agent_home> run <id>` | Direct binary execution, guarded by agent scope. Current OpenClaw sidecars use `/home/openclaw`. |346347---348349## Safety Rules350351- Do not clear or forge `variables.assignedAgent` to bypass scope.352- Do not operate on another agent's execution from this container.353- Do not mutate `processexecutions` directly. Use runner commands; if a repair path is missing, record a tool-surface gap before changing process execution state.354- Prefer scan/resume over direct `flowstate-runner run <id>` during normal operations.355- Keep inference work inside `agent-task` steps or explicit human requests; use CLI/MCP commands for deterministic process actions.356357---358359_Created: 2026-05-24_360361---362> Source: [epic-digital-im/epic-flowstate-skills](https://github.com/epic-digital-im/epic-flowstate-skills) — distributed by [TomeVault](https://tomevault.io).363<!-- tomevault:4.0:skill_md:2026-06-15 -->