ROST implementation methodCompass authoring guideInstall the ROST implementation SkillROST implementation evidence and groundingAICOS chat guideResponsibility Graph playbookCharter design playbookCharter authoring deep-diveAgent staffing playbookAdd agents to your Responsibility GraphDesign a custom agentAgent builder guideAgent definition import guideHow agents workTool access and vaultAvailable tools guideCLI and MCP installation guideSkill builder guideAgent Skill authoring guideAgent Skill setup guideAgent reference mapCascade guideSignal guideFriction guideSteward queue guideBilling and pricing guideConfirmations and human gates guideGoverned command capability matrixSettings guideMembers and invites guideNotifications guideLocal runner guideStock agents guideTroubleshooting guideAI model data handling guideSecurity model guideSync rhythm playbookMigration and legal notes
Docs

Design a custom agent

How to build a custom agent from operational questions through the Charter Builder, tools, dry run, and go-live without writing prompts.

staffingcharter design

On this page

  • Start with operational questions
  • Let the Charter Builder assemble the job
  • Choose a lane and a trigger
  • Configure tools and credentials
  • From CLI or MCP
  • Setup completeness and blockers
  • Dry run and go-live
  • When to stop for confirmation

A custom agent is for work no stock template covers. You describe the job in plain operational terms; the Charter Builder turns that into a Charter, a permission manifest, and a dry-run task. You never write a prompt — custom prompt editing is an advanced option that opens only after the operational Charter is complete, and the Charter stays the control plane.

Start with operational questions

Begin from the agents surface (Design a custom agent) or from the CLI/MCP. The wizard asks four questions:

  • What work should this seat own?
  • What does success look like? (these become Signals)
  • What must it never do alone? (these become approval and escalation boundaries)
  • Who stewards it? (the accountable human)

Let the Charter Builder assemble the job

From your answers, the Charter Builder drafts responsibilities, decision authority, Signals, handoffs, and escalation rules. Review and edit every clause. Keep the autonomous scope tight at first; you can grant more authority later once dry runs and evidence justify it.

Choose a lane and a trigger

Pick where the agent runs and what starts it. Both lead with a safe default, so a non-technical operator never has to write a raw schedule or reason about an internal lane name.

A custom agent runs on one of three lanes:

  • Cloud agent (recommended) — the ROST-managed runtime using the tenant model key. It needs no local machine, pairing, or token, so it is the default if you are unsure.
  • External MCP agent — a Claude Code, Codex, or Cursor agent that connects to ROST as the seat.
  • Local Runner — scheduled local execution through a paired Runner.

Then choose one of three named triggers:

  • On demand (default) — runs only when you or a teammate start it. No schedule.
  • Scheduled — runs on a recurring cadence you pick (every weekday morning, every morning, weekly, hourly). No cron to write.
  • Event — runs in response to work routed to it, like a sync or a mention, rather than on a clock.

Open Advanced for the explicit lane select and a raw cron expression when you need a custom cadence. A raw schedule is a five-field cron — minute hour day-of-month month day-of-week — evaluated in the agent's stored schedule timezone (UTC for agents created through this builder) and supporting *, */N steps, A-B ranges, and comma lists (for example 0 9 * * 1-5). Day-of-week is 0–7 where both 0 and 7 mean Sunday. The cron is validated when you save: an unsupported or out-of-range expression is rejected with a field-level error rather than saved as a schedule that never runs, and the builder previews the next run in the stored timezone. The builder does not currently expose a timezone selector; use the command-backed schedule update path when an existing agent must use a different canonical IANA timezone. When both day-of-month and day-of-week are set, a run fires only when both match. For schedules configured in a daylight-saving timezone, nonexistent local minutes are skipped and a repeated local minute runs once. The same schedule presets appear on the agent's seat page after go-live (Agent operations → Run schedule).

Configure tools and credentials

Propose tools, then connect or decline each one. Declining updates the permission manifest and the dry-run task so the agent still operates safely or clearly explains the blocker. Credentials are entered through write-only credential ingress and stored as vault references; raw secrets never appear in prompts, logs, or tool arguments. When a connected tool needs a credential, you stage a request with a short credential *name* — a label only. The name and its scope are validated to reject pasted secret material, so a key can never reach the append-only event log; you provide the secret itself later through the vault-backed ingress flow.

From CLI or MCP

The same path is command-backed:

1. agent_setup.start / rost_start_agent_setup with mode custom returns a setup_id. 2. Iterate with agent_setup.get and agent_setup.update (parent, Steward, lane, schedule, and the operational answers). 3. agent.create_custom / rost_create_custom_agent seeds a custom agent and a draft Charter from the operational answers only. 4. Read skill.list / rost_list_skills and, when appropriate, skill.catalog / rost_list_rost_skill_catalog; inspect skill.get plus skill.file.get for the full SKILL.md before asking a tenant-admin or human operator to assign a Skill. 5. Run skill.check_dependencies before assignment. Missing required tools are blockers for approval; optional tools are warnings. Resolve required blockers through agent.configure_tools, not by changing the Skill. 6. A tenant-admin command caller can propose the Skill with skill.assign_to_seat / rost_assign_skill_to_seat after dependency checks; a seat-scoped agent escalates the assignment request instead of calling that command. 7. agent.configure_tools / rost_configure_agent_tools records connect/decline decisions and credential-ingress requests (vault refs only). 8. agent.run_dry_run / rost_run_agent_dry_run rehearses the task after the manifest is signed.

Setup completeness and blockers

agent_setup.get derives completeness canonically, so every surface — the web builder, the CLI, and the agent.show_markdown readout — reads one result instead of doing its own math. It returns a blockers array plus a next_action. Each blocker is a typed { code, message }: consumers key off the stable code (to group blockers or deep-link to the exact repair) and show message verbatim. A setup is complete only when blockers is empty; while any blocker is present, next_action points at the highest-priority repair rather than complete.

The blocker codes are a stable vocabulary — new reasons get a new code rather than a rename. Emitted today: missing_active_charter, archived_parent, missing_parent, missing_steward, and skill_dependency_blocked (missing_occupancy and missing_goal_or_measurable are reserved for later checks).

Completeness is not just a draft gate: a live agent is not automatically complete. If a live seat has no active, approved Charter, its configured parent is archived, or its steward chain no longer resolves to a human, agent_setup.get surfaces the matching blocker and routes next_action to the fix — fix_charter for missing_active_charter, fix_reporting_line for archived_parent, then set_steward for missing_steward, in that priority order. A live agent with no configured parent at all is the legitimate top-level case and stays complete; only an archived configured parent blocks it.

Dry run and go-live

The dry run is a real sandbox rehearsal, not a stamp. It executes a mock-provider run derived from the Charter — the agent works against sandbox data only and is expected to escalate where the Charter's must-escalate clause requires it. The same rehearsal works on all three lanes: cloud, external MCP, and local Runner. External MCP dry runs require an active seat-scoped MCP token; Runner dry runs require a paired Runner. Missing substrate returns a typed precondition error, not a generic failure. The recorded run keeps the agent's actual lane, so the evidence you review matches the lane you selected. The result is earned: a run that escalates the must-escalate boundary passes; a run that acts on that boundary instead of escalating fails. A failed dry run keeps the draft and shows the reason so you can edit and rerun. The rehearsal returns a transcript — the steps the agent took and the escalation it raised — shown step by step in the builder and printed by the CLI, so you can see the governance model working before anything goes live. The transcript is also lane-honest: each granted tool is marked executable, held for the steward, or granted but unimplemented in this lane, with a plain-count verdict such as "2 of 6 granted tools don't execute in the cloud lane yet" — so a grant that would silently no-op in the cloud runtime is visible before go-live instead of passing green. Runner and MCP-session agents run those tools through their own local skills, so their grants are not flagged as unimplemented. When the dry run passes, a human promotes the agent live. The dry run rehearses the specific model tier you chose, so once it passes the model is locked — changing the model requires re-running the dry run on the new model before go-live.

When to stop for confirmation

agent.create_custom, charter.sign_manifest, staffing.assign_user, and agent.go_live are human_required; agent.configure_tools and credential.ingress are credential_flow (both gate through the vault-backed credential path with human approval; agent.configure_tools stages the request and only credential.ingress takes the raw secret, as a vault reference). agent.run_dry_run is ungated by human approval but requires a signed manifest first — a dry run before charter.sign_manifest returns a clean COMMAND_PRECONDITION_FAILED pointing at charter.sign_manifest. The go-live after a passed dry run is human_required. An agent may draft, configure (with vault refs), and dry-run; only a human approves the Charter, manifest, credentials, and go-live. A seat token can never create or approve its own setup. See the confirmations guide.

Version

2026-07-12.2

Used by

  • human
  • cli
  • mcp
  • in app agent

API

/api/reference/files/custom-agents-guide