DocsConfigure

Profiles & workflows

Design how agents work in the Behaviors editor, and understand the plain JSON files behind it.

A single agent loop decides its own path. A workflow decides it for the agent: which steps run, what each may use, what must be verified, and what happens on failure. Each agent step runs under a profile that sets its instructions, tools, limits and completion checks.

Both are edited in the Behaviors tab and stored as plain JSON in your workspace:

Kind Location
Profiles .rusty/profiles/<id>.json
Workflows .rusty/workflows/<id>.json

Note

Rusty ships with 12 profiles and 15 workflows, available in every project. Choose one from the Mode menu in Agent Mode. They are read-only, so they always stay in a known-good state. To change one, choose Customize a copy: you get your own editable copy, saved in your workspace. This page is about customizing and writing your own. To learn what the built-in ones do and how to run them, start with Workflows.

The Behaviors editor

Open Behaviors in the left rail. A switch at the top left toggles between Workflows and Profiles, and the list beside it shows what you have. The built-in workflows and profiles are tagged Built-in.

  • The workflow view draws steps as nodes and their connections as edges. The buttons above the canvas add steps: Input, Agent, Verify and Output. Select a step or an edge to edit it in the inspector, drag from a step's right handle to another step to connect them, and drill into an agent step to see its profile.
  • The profile view draws profiles as nodes, with switch_profile rules drawn as edges between them.
  • Steps show the state of the latest run, such as succeeded or running, and a badge such as Last run cancelled summarizes it.
  • Run in Agent Mode starts the selected workflow from Agent Mode, with that chat's model and tools. New workflow creates one.
  • Edits are validated as you make them, and a step or profile with a validation problem is flagged.
  • A dot marks unsaved changes, and the button at the top right reads Saved when everything is written.

For a built-in workflow the inspector is read-only and says Built into Rusty · available in every project, with Customize a copy at the top.

The workflow inspector

With nothing selected, the inspector at the right edits the workflow itself:

Field Meaning
Name and Description How the workflow is listed and described.
Revision A number you can bump as you change it.
Status Draft, Published or Deprecated.
Optional limits Budgets for a whole run. Leave a field empty for no limit.

The optional limits are Steps, Total attempts, Duration (seconds), Model requests, Tool calls, Tokens and Cost (USD). You can also stop a running workflow at any time.

Because the documents are plain JSON, fields the editor does not know about survive a load and save. Use the JSON toggle in the inspector header to see and edit a document's raw JSON. Canvas positions are stored under metadata.editor.position, which the engine ignores.

Run a workflow

In Agent Mode, the Mode menu above the message box picks what the chat follows: Single agent, a Stage, a Workflow, or Auto. See Workflows for how to run one and how stages build on each other, and Auto flows for letting Rusty choose.

While a chat follows a workflow, the skill menu stays on build and reads tools set per step: each step's profile decides its tools.

Built-in profiles and workflows

The 12 built-in profiles (Research, Analyze, Plan, Architect, Debug, Build, Verify, Review, Security, Document, Refactor and Optimize) and 15 built-in workflows are described in Built-in workflows, including what each step can do. Their IDs start with rusty-ide.builtin.. Customize a copy to start from any of them.

Profiles

A profile describes what one agent step may do. This is the built-in Plan profile, trimmed. (In the app its ID is rusty-ide.builtin.plan; your own profiles use the IDs you give them.)

{
  "schema_version": 1,
  "id": "plan",
  "revision": 3,
  "name": "Plan",
  "description": "Read-only investigation. Explores the workspace and produces a concrete plan.",
  "status": "draft",
  "instructions": {
    "mode": "append",
    "text": "Investigate the request and write an actionable implementation plan..."
  },
  "tools": {
    "type": "allow_list",
    "tools": ["read_file", "list_files", "search_codebase", "web_search", "web_extract", "report_progress", "ask_user_question"]
  },
  "rules": [
    {
      "id": "plan-read-only",
      "on": "PreToolUse",
      "when": { "tool": ["write_file", "run_command"] },
      "do": { "deny": { "reason": "The plan step is read-only. Describe the change in the plan instead of making it." } }
    }
  ],
  "completion_gate": {
    "checks": [
      {
        "id": "explored-first",
        "require": { "calls": { "tool": ["read_file", "list_files", "search_codebase"], "gte": 1 } },
        "feedback": "You have not looked at the code yet. Explore the relevant files before proposing a plan."
      }
    ],
    "max_continuations": 2,
    "on_exhausted": "fail"
  }
}

Profile fields

Field What it does
id, name, description, revision, status Identity and bookkeeping. Built-in profiles have IDs starting with rusty-ide.builtin..
instructions Text added to the agent's instructions. mode: "append" adds to the base instructions.
tools Which tools the step may use. { "type": "inherit" } keeps whatever the surrounding session allows. { "type": "allow_list", "tools": [...] } limits it to the named tools.
tool_overrides Adjusts how a tool is described to the model, for example description_append to add a guideline to write_file.
limits Optional turn and tool-call limits. Unset in the built-in flow.
rules Event-driven rules that steer the agent. See below.
completion_gate Checks the agent must satisfy before it is allowed to finish. See below.
children Settings for subagents this step starts. { "type": "inherit" } is the default.

Rules

A rule reacts to an event and takes an action.

{
  "id": "build-failed-tool",
  "on": "PostToolUseFailure",
  "do": { "inject": { "text": "That tool call failed. Read the error and fix the cause; do not repeat the same call unchanged." } },
  "max_fires": 8
}
Part Values
on (event) RunStart, BeforeModelRequest, PreToolUse, PostToolUse, PostToolUseFailure, ProfileEntered
when (optional filter) For example { "tool": ["write_file"] } to match specific tools, or { "turn": { "gte": 3 } } to match after a number of turns.
do (action) inject, deny, ask, allow, stop_run, switch_profile, rewrite_args, rewrite_result
max_fires Optional cap on how many times the rule can trigger.

Which actions are valid depends on the event:

Action Effect Valid on
inject Adds guidance text to the conversation. Any event
deny Blocks the tool call, with a reason the agent sees. PreToolUse
ask Asks you first. PreToolUse
allow Allows the call to proceed. PreToolUse
rewrite_args Merges values into the call's arguments. PreToolUse
rewrite_result Edits a tool's result before the agent sees it. PostToolUse, PostToolUseFailure
stop_run Ends the run, with a reason. Any event
switch_profile Hands the run to another profile. Any event except ProfileEntered

Completion gates

A completion gate stops an agent from declaring victory too early. Each check has a require condition and a feedback message the agent receives when the check fails. The agent is sent back to keep working up to max_continuations times; if it still fails, on_exhausted: "fail" fails the step.

The built-in Build profile uses this to require that any edit is followed by a check:

{
  "id": "checked-after-editing",
  "require": {
    "any": [
      { "calls": { "tool": "write_file", "eq": 0 } },
      { "since_last_call": { "of": "write_file", "called": ["run_command", "read_file"], "gte": 1 } }
    ]
  },
  "feedback": "You changed files but have not checked them since your last edit. Run the project's tests or type-check, or read the changed file back, then report."
}

In words: either no files were written, or since the last write the agent ran a command or read a file at least once.

Workflows

A workflow is a graph of steps. This is the shape of the built-in flow, abbreviated. Customize a copy starts you from exactly this:

{
  "schema_version": 1,
  "id": "plan-build-verify",
  "name": "Plan, build, verify",
  "status": "draft",
  "nodes": [
    { "id": "input", "name": "Request", "type": "input" },
    {
      "id": "plan", "name": "Plan", "type": "agent",
      "config": {
        "instructions": "Investigate the request and write an actionable implementation plan...",
        "tools": { "type": "inherit" },
        "context_mode": "isolated_child",
        "structured_output": "text",
        "profile": { "id": "plan" }
      },
      "input_bindings": [
        { "target": "request", "source": { "type": "run_input", "pointer": "/request" } }
      ]
    },
    {
      "id": "build", "name": "Build", "type": "agent",
      "config": { "context_mode": "isolated_child", "structured_output": "text", "profile": { "id": "build" } },
      "input_bindings": [
        { "target": "request", "source": { "type": "run_input", "pointer": "/request" } },
        { "target": "plan", "source": { "type": "node_output", "node_id": "plan", "pointer": "" } }
      ]
    },
    {
      "id": "verify", "name": "Verify", "type": "agent",
      "config": { "context_mode": "isolated_child", "structured_output": "text", "profile": { "id": "verify" } },
      "input_bindings": [
        { "target": "request", "source": { "type": "run_input", "pointer": "/request" } },
        { "target": "plan", "source": { "type": "node_output", "node_id": "plan", "pointer": "" } },
        { "target": "build", "source": { "type": "node_output", "node_id": "build", "pointer": "" } }
      ]
    },
    {
      "id": "output", "name": "Result", "type": "output",
      "config": { "source": { "type": "node_output", "node_id": "verify", "pointer": "" } }
    }
  ],
  "edges": [
    { "id": "input-plan", "source": "input", "target": "plan", "condition": "on_success" },
    { "id": "plan-build", "source": "plan", "target": "build", "condition": "on_success" },
    { "id": "build-verify", "source": "build", "target": "verify", "condition": "on_success" },
    { "id": "verify-output", "source": "verify", "target": "output", "condition": "on_success" }
  ]
}

Steps

Step type Purpose
input Receives the request that starts the run.
agent Runs an agent, optionally under a profile.
verify Validates a previous step's output against checks, for example a schema.
output Picks which step's output becomes the workflow's result.

Every agent step runs in a fresh, isolated session (context_mode: "isolated_child") that inherits your workspace, active model and permission policies. Steps hand work to each other as ordinary text or Markdown, not a fixed JSON schema. A finished workflow means the sequence finished, not that its review approved the implementation, so read the Verify step's verdict.

Inputs and edges

  • input_bindings say where each named input to a step comes from: the run's input (run_input) or another step's output (node_output).
  • edges connect steps. condition is on_success for the normal path or on_failure to route a failure somewhere else.
  • retry on a step sets a bounded number of attempts (max_attempts).

Limits and timeouts

Workflow budgets (see the inspector fields above), profile turn and tool-call limits, and step timeouts are all optional, and none is set in the built-in flow. The editor offers numeric fields for them, checkboxes for context, and a selector for the result source. Workflows written as raw JSON keep working through the advanced settings.

Choosing and switching flows

Two optional fields in a workflow's metadata (which the engine ignores) let Auto and flow switching work with it. The built-in workflows set them; your own can too.

"metadata": {
  "route": { "when": "The user wants to understand how existing functionality works before deciding anything." },
  "switch_to": ["diagnose", "security-audit"]
}
Field Meaning
route.when When this workflow is the right one for a message, in a sentence or two. The decision model reads it. A workflow without it is never picked by Auto.
switch_to Ids of the workflows this one may hand over to when flow switching is on. Use the workflow's id; for a built-in workflow, the id without rusty-ide.builtin.. A workflow without it never hands over.

Whether a workflow can change files is not declared: Rusty reads it from the profiles its steps use. A workflow edits unless every agent step's profile either has an allow-list without write_file, or has a PreToolUse rule that denies write_file. Auto and flow switching ask before starting one that does.

The built-in workflows hand over only to the read-only stages. For example Plan, build, verify may hand over to Research & analyze, Debug & plan a fix or Security audit & fix plan.

Tips

Tip

Start from Customize a copy of the built-in flow rather than writing from scratch. Change a profile's instructions, add a deny rule for a command you never want run, or tighten the tool allow-list, and watch how the next run behaves.

  • Commit .rusty/profiles/ and .rusty/workflows/ so your team shares the same behavior.
  • Keep completion-gate feedback specific. It is the message the agent acts on.
  • Use deny and ask rules for guardrails. See Permissions & safety.
Esc

Type to search the docs.