Skip to content

team.yaml reference

The team config lives at .outstaff/team.yaml in your repository. For a prose tour of the sections, see Team config. Problems found by ost validate are listed in Validation codes. The same schema is published as JSON Schema in packages/core/schema/team.schema.json.

Paths use [] for list items and <key> for a map entry whose key you choose.

Only the office loads this file. Each agent receives it from the office when it connects, whole, so it holds no secrets: fields such as people[].network.http[].token name a secret, and each container reads the value from its own secrets.

A complete file for the synthetic team “acme”.

# Synthetic example: the "acme" team does not exist. All names, handles,
# addresses and URLs below are made up. It is used by tests and docs.
# Schema version of this file; currently 1.
version: 1
# Who the team is.
team:
name: acme
product: Acme Shop
description: The team that builds and runs Acme Shop.
# Trusted humans. Optional; when omitted, trusted humans are repo writers and full chat-workspace members.
humans:
- name: Ada Admin
identities:
vcs: ada-admin
tracker: ada.admin
chat: U0ADA0001
email: ada@acme.example
- name: Grace Lead
identities:
vcs: grace-lead
chat: U0GRACE02
# Which catalog of roles and skills the team uses.
catalog:
version: 0.0.0
# Repositories the team works in; at least one.
repos:
- name: shop
url: github.com/acme-example/shop
kind: primary
checks:
- pnpm lint
- pnpm vitest related --run
- name: infra
url: github.com/acme-example/infra
kind: infra
- name: design-system
url: github.com/acme-example/design-system
kind: baseline
- name: docs-site
url: github.com/acme-example/docs-site
kind: other
# The agents on the team; may be empty.
people:
- handle: priya
name: Priya Raman
pronouns: she/her
role: pm
model: sonnet
identities:
vcs: acme-priya[bot]
chat: U0PRIYA03
tracker: priya.raman
repos:
"*": read
docs-site: write
- handle: tomas
name: Tomas Novak
pronouns: he/him
role: product
model: sonnet
identities:
vcs: acme-tomas[bot]
chat: U0TOMAS04
tracker: tomas.novak
repos:
"*": read
docs-site: write
- handle: mira
name: Mira Okafor
pronouns: she/her
role: architect
model: opus
extends: [developer]
identities:
vcs: acme-mira[bot]
chat: U0MIRA005
tracker: mira.okafor
repos:
shop: write
"kind:baseline": read
- handle: leo
name: Leo Fischer
pronouns: he/him
role: designer
model: sonnet
identities:
chat: U0LEO0006
tracker: leo.fischer
- handle: sam
name: Sam Duarte
pronouns: they/them
role: developer
model: sonnet
identities:
vcs: acme-sam[bot]
chat: U0SAM0007
tracker: sam.duarte
repos:
shop: write
"kind:baseline": read
- handle: noor
name: Noor Haddad
pronouns: she/her
role: developer
model: sonnet
identities:
vcs: acme-noor[bot]
chat: U0NOOR008
tracker: noor.haddad
repos:
shop: write
"kind:baseline": read
- handle: ines
name: Ines Varga
pronouns: she/her
role: reviewer
model: sonnet
identities:
vcs: acme-ines[bot]
chat: U0INES009
tracker: ines.varga
repos:
"*": read
- handle: kofi
name: Kofi Mensah
pronouns: he/him
role: devops
model: sonnet
identities:
vcs: acme-kofi[bot]
chat: U0KOFI010
tracker: kofi.mensah
repos:
infra: write
shop: read
# Which adapters connect Outstaff to your tools.
integrations:
chat:
adapter: slack
vcs:
adapter: github
runtime:
adapter: claude-agent-sdk
tracker:
adapter: itsaplan
url: https://tracker.acme.example
project: SHOP
knowledge:
adapter: itsaplan
avatars:
adapter: dicebear
style: notionists
# Where agents keep their memory: the lasting lessons and preferences they note.
memory:
# Each agent's notes on a page of its own in the knowledge integration. The default, volume, keeps them in memory/ on
# each agent's home volume, which you then back up.
store: knowledge
# How the tracker's statuses and labels map onto outstaff's.
workflow:
statuses:
backlog: Backlog
ready: Ready
active: In Progress
review: In Review
blocked: Blocked
done: Done
canceled: Canceled
# Team-wide guardrails, message style and switches for what outstaff does on its own.
policies:
# What outstaff does on its own. Everything below is on by default; set a switch to false (or none) to turn it off.
acknowledge:
chat: true
vcs: true
chat:
profile: true
design:
canvas: true
feedback:
follow_up_round: true
hand_back:
fallback: first_human
tickets:
prs_per_ticket: one
messages:
max_lines: 3
# Event pipeline policies of the team's own, loaded from this repository. See "Writing a policy" in the docs.
custom:
- module: ./policies/release-freeze.ts
settings:
until: "2026-12-01T00:00:00Z"
label: hotfix

Schema version of this file; currently 1.

  • Type: number
  • Required
  • Must be 1

Who the team is.

  • Type: object
  • Required

Team slug: lowercase letters, digits and dashes, starting with a letter.

  • Type: string
  • Required
  • Minimum length 1
  • Maximum length 40
  • Must match ^[a-z][a-z0-9-]*$

Name of the product the team builds.

  • Type: string
  • Optional

One-line description of the team.

  • Type: string
  • Optional

Trusted humans. Optional; when omitted, trusted humans are repo writers and full chat-workspace members.

  • Type: list of object
  • Optional

A trusted human.

  • Type: object
  • Optional

Display name of the trusted human.

  • Type: string
  • Required
  • Minimum length 1

How this human is known on each connected system; at least one is required.

  • Type: object
  • Required

Username on the VCS host.

  • Type: string
  • Optional
  • Minimum length 1

Username or id in the issue tracker.

  • Type: string
  • Optional
  • Minimum length 1

Username or id in the chat workspace.

  • Type: string
  • Optional
  • Minimum length 1

Email address.

  • Type: string
  • Optional
  • Minimum length 1

Which catalog of roles and skills the team uses.

  • Type: object
  • Required

Exact catalog release this team uses, for example “1.0.0”; must match the catalog in the agent images.

  • Type: string
  • Required
  • Minimum length 1

Directory of ejected catalog files, relative to this file.

  • Type: string
  • Optional
  • Default: catalog
  • Minimum length 1

Repositories the team works in; at least one.

  • Type: list of object
  • Required
  • Minimum items 1

A repository the team works in.

  • Type: object
  • Optional

Short name used to refer to this repository in grants.

  • Type: string
  • Required
  • Minimum length 1
  • Maximum length 40
  • Must match ^[a-z][a-z0-9-]*$

Repository location: host/owner/repo, an https URL or a git@ address.

  • Type: string
  • Required
  • Must match ^(https?:\/\/\S+|git@\S+:\S+|[A-Za-z0-9.-]+\/[\w.-]+\/[\w.-]+)$

Role of the repository: primary (the product, at most one), baseline, infra or other.

  • Type: string
  • Required
  • Allowed values: primary, baseline, infra, other

Branch that pull requests target.

  • Type: string
  • Optional
  • Default: main
  • Minimum length 1

Commands an agent runs before pushing, covering only what a change affects (for example lint and the tests related to changed files). CI runs the full suite. When omitted, agents work out the affected checks themselves.

  • Type: list of string
  • Optional
  • Minimum items 1
  • Type: string
  • Optional
  • Minimum length 1

How work is done in this repository, as free text: commits, branches, pull request title and body, tests. For repositories whose own files (CONTRIBUTING.md, AGENTS.md, the pull request template) cannot say it. Agents read it in addition to those files.

  • Type: string
  • Optional
  • Minimum length 1

Extra ways this repository’s pull request body names its ticket, as regular expressions with one {key} placeholder for the ticket key (for example Ticket: {key}). A pull request is always linked by the ticket key in its branch name, its title, or a closing keyword in its body (Closes ACME-12); these patterns add to the last. A key mentioned in the body in any other way links nothing.

  • Type: list of string
  • Optional
  • Minimum items 1
  • Type: string
  • Optional
  • Minimum length 1
  • Maximum length 200

Extra files in this repository that agents read before they work, relative to its root, for example [“CLAUDE.md”]. A project CLAUDE.md is not loaded into agent sessions unless it is listed here.

  • Type: list of string
  • Optional
  • Minimum items 1
  • Type: string
  • Optional
  • Minimum length 1

Which tracker tickets this repository serves. Agents use it to decide where a ticket’s work goes when the ticket does not name a repository.

  • Type: object
  • Optional

Ticket labels that mean the work belongs in this repository.

  • Type: list of string
  • Required
  • Minimum items 1
  • Type: string
  • Optional
  • Minimum length 1

The agents on the team; may be empty.

  • Type: list of object
  • Required

An AI agent on the team.

  • Type: object
  • Optional

Unique lowercase handle; used as the agent’s hostname label and mention name.

  • Type: string
  • Required
  • Minimum length 1
  • Maximum length 30
  • Must match ^[a-z][a-z0-9-]*$

Display name of the agent.

  • Type: string
  • Required
  • Minimum length 1

Pronouns shown in the agent’s profile.

  • Type: string
  • Optional

Catalog role this agent plays, for example “developer”.

  • Type: string
  • Required
  • Minimum length 1

Extra catalog roles or skill bundles layered on top of the role.

  • Type: list of string
  • Optional
  • Type: string
  • Optional
  • Minimum length 1

LLM model this agent runs on, as the runtime adapter names it, for example “sonnet”. Required: there is no default model.

  • Type: string
  • Required
  • Minimum length 1

Runtime adapter for this agent, in the same shape as integrations.runtime: adapter and that adapter’s options. It replaces the team’s runtime for this agent as a whole (options are not merged); integrations.runtime when omitted.

  • Type: object
  • Optional

Name of the adapter package to use, for example “github”.

  • Type: string
  • Required
  • Minimum length 1

How this agent is known on each connected system. The office recognizes the agent’s own activity only by an exact match with these.

  • Type: object
  • Optional

Login of this agent on the VCS host, for example “acme-sam[bot]”.

  • Type: string
  • Optional
  • Minimum length 1

Username or id of this agent in the issue tracker.

  • Type: string
  • Optional
  • Minimum length 1

Username or id of this agent in the chat workspace.

  • Type: string
  • Optional
  • Minimum length 1

Repository access by repo name, “kind:<primary|baseline|infra|other>” or “*”; values are “read” or “write”.

  • Type: map
  • Optional
  • Default: {}

Tools for this agent only; they replace team-level tools of the same name.

  • Type: map
  • Optional

A tool installed at agent start, and optionally a narrower set of commands it may run.

  • Type: object
  • Optional

Exact version to install, for example “1.23.4”.

  • Type: string
  • Required

Where mise gets the tool, as a mise backend and name such as ubi:vendor/their-cli or npm:their-cli. Defaults to the tool name, which mise looks up in its registry.

  • Type: string
  • Optional
  • Must match ^[a-z0-9_-]+:\S+$

Options mise passes to the tool’s backend, such as url, bin_path and checksum for an http: source. A value is a string, or a map for platform-keyed options: platforms: { linux-x64: { url: “…” } }. Needs source.

  • Type: map
  • Optional

Options of the tool that take their value as the next word, such as -c or –context. Their values are never taken for a subcommand, so a rule finds delete in acmectl -c prod delete. --option=value is one word and needs no entry.

  • Type: list of string
  • Optional
  • Minimum items 1
  • Type: string
  • Optional
  • Must match ^--?[^\s=-][^\s=]*$

Narrows what the agent may run of the tool: “all” (the default: any arguments), a list of subcommands, or structured rules. With a list or rules, only the commands they match run. When an option before the subcommand is not in valued_options and might take the next word as its value, every way of reading the command must be allowed. Deny rules and the built-in denies still win.

  • Type: string or list of string or list of object
  • Optional
  • Type: string
  • Optional
  • Minimum length 1

Commands of the tool the agent may never run: a list of subcommands, or structured rules. Deny always wins over allow, including “all”. A deny rule also looks past the value of a leading option that is not in valued_options, so -x value delete cannot hide a denied delete.

  • Type: list of string or list of object
  • Optional
  • Type: string
  • Optional
  • Minimum length 1

Network grants for this agent, merged over those of its roles.

  • Type: object
  • Optional

Services reachable with ost http.

  • Type: list of object
  • Optional

A service the agent may reach with ost http.

  • Type: object
  • Optional

Name the agent gives to ost http, for example hub.

  • Type: string
  • Required
  • Minimum length 1
  • Maximum length 30
  • Must match ^[a-z][a-z0-9-]*$

Origin of the service, for example https://hub.acme.example.

  • Type: string
  • Required

Key of a secret in this person’s secrets; sent as Authorization: Bearer <value> to this service. The agent never sees the value.

  • Type: string
  • Optional
  • Must match ^[A-Za-z0-9_]+$

Avatar settings.

  • Type: object
  • Optional

Seed for a generated avatar.

  • Type: string
  • Optional

Image URL to use as the avatar.

  • Type: string
  • Optional

Which adapters connect Outstaff to your tools.

  • Type: object
  • Required

Chat adapter where humans and agents talk.

  • Type: object
  • Required

Name of the adapter package to use, for example “github”.

  • Type: string
  • Required
  • Minimum length 1

Version control adapter (repositories and pull requests).

  • Type: object
  • Required

Name of the adapter package to use, for example “github”.

  • Type: string
  • Required
  • Minimum length 1

LLM runtime adapter that runs the agents; the default for everyone without a runtime of their own (people[].runtime).

  • Type: object
  • Required

Name of the adapter package to use, for example “github”.

  • Type: string
  • Required
  • Minimum length 1

Issue tracker adapter.

  • Type: object
  • Optional

Name of the adapter package to use, for example “github”.

  • Type: string
  • Required
  • Minimum length 1

Knowledge base adapter.

  • Type: object
  • Optional

Name of the adapter package to use, for example “github”.

  • Type: string
  • Required
  • Minimum length 1

Avatar generation adapter.

  • Type: object
  • Optional

Name of the adapter package to use, for example “github”.

  • Type: string
  • Required
  • Minimum length 1

Email addresses for agents.

  • Type: object
  • Optional

Address pattern for agents, for example “{handle}@acme.example”.

  • Type: string
  • Required

Office settings: event intake and the doctor checks.

  • Type: object
  • Optional

How the office learns about changes: polling or webhooks.

  • Type: string
  • Optional
  • Default: poll
  • Allowed values: poll, webhook

Seconds between polls when events is “poll”.

  • Type: integer
  • Optional
  • Default: 60
  • Minimum 10
  • Maximum 3600

Minutes without a successful poll of an event source before the office logs a warning. Default 10.

  • Type: integer
  • Optional
  • Minimum 1
  • Maximum 1440

Team chat channel where the office mirrors agent-to-agent questions and answers, so humans can follow them. Without it they go to the ticket of the asking work item, or only to its journal.

  • Type: string
  • Optional
  • Minimum length 1

When the office runs the doctor checks itself, and which it leaves out.

  • Type: object
  • Optional

Time of day (HH:MM, 24-hour, in the office’s time zone: the container’s TZ, UTC unless set) the office runs the doctor checks every day. It also runs them at start, on demand and, while one fails or warns, every retry_minutes.

  • Type: string
  • Optional
  • Default: 06:00
  • Must match ^([01]\d|2[0-3]):[0-5]\d$

Minutes between the office’s re-runs of its doctor checks while one of them fails or warns, or a run could not finish. They stop once every check passes. 0 turns the re-runs off.

  • Type: integer
  • Optional
  • Default: 15
  • Minimum 0
  • Maximum 1440

Ports (for example chat) whose adapter’s live checks the office does not run, for a provider the office cannot or should not call. Their secrets are still checked; ost doctor still runs them.

  • Type: list of string
  • Optional
  • Allowed values: chat, vcs, runtime, tracker, knowledge, avatars
  • Type: string
  • Optional
  • Allowed values: chat, vcs, runtime, tracker, knowledge, avatars

Tools every agent of the team installs at start, with the commands they may run.

  • Type: map
  • Optional

A tool installed at agent start, and optionally a narrower set of commands it may run.

  • Type: object
  • Optional

Exact version to install, for example “1.23.4”.

  • Type: string
  • Required

Where mise gets the tool, as a mise backend and name such as ubi:vendor/their-cli or npm:their-cli. Defaults to the tool name, which mise looks up in its registry.

  • Type: string
  • Optional
  • Must match ^[a-z0-9_-]+:\S+$

Options mise passes to the tool’s backend, such as url, bin_path and checksum for an http: source. A value is a string, or a map for platform-keyed options: platforms: { linux-x64: { url: “…” } }. Needs source.

  • Type: map
  • Optional

Options of the tool that take their value as the next word, such as -c or –context. Their values are never taken for a subcommand, so a rule finds delete in acmectl -c prod delete. --option=value is one word and needs no entry.

  • Type: list of string
  • Optional
  • Minimum items 1
  • Type: string
  • Optional
  • Must match ^--?[^\s=-][^\s=]*$

Narrows what the agent may run of the tool: “all” (the default: any arguments), a list of subcommands, or structured rules. With a list or rules, only the commands they match run. When an option before the subcommand is not in valued_options and might take the next word as its value, every way of reading the command must be allowed. Deny rules and the built-in denies still win.

  • Type: string or list of string or list of object
  • Optional
  • Type: string
  • Optional
  • Minimum length 1

Commands of the tool the agent may never run: a list of subcommands, or structured rules. Deny always wins over allow, including “all”. A deny rule also looks past the value of a leading option that is not in valued_options, so -x value delete cannot hide a denied delete.

  • Type: list of string or list of object
  • Optional
  • Type: string
  • Optional
  • Minimum length 1

Settings per catalog role, for everyone who plays it.

  • Type: map
  • Optional

Settings for everyone who plays this role.

  • Type: object
  • Optional

Network grants every person with this role gets, merged with their own.

  • Type: object
  • Optional

Services reachable with ost http.

  • Type: list of object
  • Optional

A service the agent may reach with ost http.

  • Type: object
  • Optional

Name the agent gives to ost http, for example hub.

  • Type: string
  • Required
  • Minimum length 1
  • Maximum length 30
  • Must match ^[a-z][a-z0-9-]*$

Origin of the service, for example https://hub.acme.example.

  • Type: string
  • Required

Key of a secret in this person’s secrets; sent as Authorization: Bearer <value> to this service. The agent never sees the value.

  • Type: string
  • Optional
  • Must match ^[A-Za-z0-9_]+$

How the tracker’s statuses and labels map onto outstaff’s.

  • Type: object
  • Optional

Maps canonical statuses to the status names used in your tracker.

  • Type: map
  • Optional
  • Allowed keys: backlog, ready, active, review, blocked, done, canceled

Ticket label that keeps work with a human. Default “needs-human”.

  • Type: string
  • Optional
  • Minimum length 1

The event pipeline, which decides what the office does with every event (decision 0018): changes to its default policies, how wakes are batched, and the context every wake carries.

  • Type: object
  • Optional

Changes to the built-in and custom policies, by policy id.

  • Type: map
  • Optional

Changes to one policy of the event pipeline.

  • Type: object
  • Optional

Set to false to turn the policy off. Default: the policy’s own default.

  • Type: boolean
  • Optional

The instruction a woken agent is given, with {{variable}} placeholders. Replaces the policy’s default text.

  • Type: string
  • Optional
  • Minimum length 1

An extra condition that must hold as well: narrows the policy, never widens it.

  • Type: object
  • Optional
  • Type: list of condition
  • Required
  • Minimum items 1
  • Type: condition
  • Optional
  • Type: list of condition
  • Required
  • Minimum items 1
  • Type: condition
  • Optional
  • Type: condition
  • Required
  • Type: list of string
  • Required
  • Allowed values: backlog, ready, active, review, blocked, done, canceled
  • Minimum items 1
  • Type: string
  • Optional
  • Allowed values: backlog, ready, active, review, blocked, done, canceled
  • Type: list of string
  • Required
  • Allowed values: backlog, ready, active, review, blocked, done, canceled
  • Minimum items 1
  • Type: string
  • Optional
  • Allowed values: backlog, ready, active, review, blocked, done, canceled
  • Type: list of string
  • Required
  • Allowed values: backlog, ready, active, review, blocked, done, canceled
  • Minimum items 1
  • Type: string
  • Optional
  • Allowed values: backlog, ready, active, review, blocked, done, canceled
  • Type: string
  • Required
  • Allowed values: human, agent, automation
  • Type: string
  • Required
  • Allowed values: human, agent, none
  • Type: string
  • Required
  • Minimum length 1
  • Type: string
  • Required
  • Allowed values: human, agent, bot
  • Type: boolean
  • Required
  • Type: boolean
  • Required
  • Type: boolean
  • Required
  • Type: boolean
  • Required
  • Type: boolean
  • Required
  • Type: boolean
  • Required
  • Type: boolean
  • Required
  • Type: list of string
  • Required
  • Minimum items 1
  • Type: string
  • Optional
  • Minimum length 1
  • Type: list of string
  • Required
  • Allowed values: done, waiting, blocked, silent
  • Minimum items 1

pipeline.policies..when.hand_back_status[]

Section titled “pipeline.policies..when.hand_back_status[]”
  • Type: string
  • Optional
  • Allowed values: done, waiting, blocked, silent
  • Type: list of string
  • Required
  • Minimum items 1
  • Type: string
  • Optional
  • Minimum length 1
  • Type: boolean
  • Required

pipeline.policies..when.ticket_prs_all_closed

Section titled “pipeline.policies..when.ticket_prs_all_closed”
  • Type: boolean
  • Required
  • Type: boolean
  • Required

pipeline.policies..when.ticket_prs_several

Section titled “pipeline.policies..when.ticket_prs_several”
  • Type: boolean
  • Required
  • Type: boolean
  • Required
  • Type: boolean
  • Required

pipeline.policies..when.ticket_handed_back

Section titled “pipeline.policies..when.ticket_handed_back”
  • Type: boolean
  • Required
  • Type: boolean
  • Required
  • Type: boolean
  • Required

How wakes are batched.

  • Type: object
  • Optional

Wakes for the same person and subject within this many seconds of the first become one run, which starts when the window closes. A chat message is answered at once: its wake waits for no window, though a message for a session still queued joins it. Default 60; 0 turns it off.

  • Type: integer
  • Optional
  • Minimum 0
  • Maximum 3600

How the direct messages that tell a human about work that landed on them are batched.

  • Type: object
  • Optional

How long a direct message to a human about work that landed on them (the notify_human_on_handoff policy) waits for more to join it: an agent’s messages to one human within this many seconds of the latest go as one. A message also waits while the agent’s round on its ticket runs, so a pull request opened in a round goes with the round’s hand-back. Default 60, or office.poll_interval_seconds plus 15 when that is longer, so a pull request the office reads after the hand-back still joins its message.

  • Type: integer
  • Optional
  • Minimum 0
  • Maximum 3600

The context bundle every wake carries: the tickets, pull requests and chat threads the work is linked to, with their recent comments, threads and messages.

  • Type: object
  • Optional

The latest comments of each ticket handed over. Default 5.

  • Type: integer
  • Optional
  • Minimum 0
  • Maximum 50

The latest messages of each chat thread handed over. Default 10.

  • Type: integer
  • Optional
  • Minimum 0
  • Maximum 50

The unresolved review threads of each pull request handed over. Default 5.

  • Type: integer
  • Optional
  • Minimum 0
  • Maximum 50

The latest review comments on the pull requests of the ticket being worked on and of its parent, resolved and merged ones included. Default 10.

  • Type: integer
  • Optional
  • Minimum 0
  • Maximum 50

How many tickets, pull requests, documents and chat threads one wake carries at most, the closest to what woke the agent first. Default 8.

  • Type: integer
  • Optional
  • Minimum 1
  • Maximum 50

Longer descriptions, comments and messages are cut to this many characters; the link has the rest. Default 1500.

  • Type: integer
  • Optional
  • Minimum 100
  • Maximum 20000

Proposed (decision 0016): a monitoring or management service the office connects out to, with the secret OUTSTAFF_LINK_TOKEN, that shows its people, queues and event traces (a dashboard, for example). Without it, or without the token, the office connects to none.

  • Type: object
  • Optional

Where the office connects, for example wss://ops.acme.example/link.

  • Type: string
  • Required
  • Must match ^wss?:\/\/\S+$

Team-wide guardrails, message style and switches for what outstaff does on its own.

  • Type: object
  • Optional

Stops agents from triggering each other in endless loops. Limits only runs triggered by agents or automation; humans are never limited.

  • Type: object
  • Optional
  • Default: {"max_runs_per_subject_per_hour":12}

policies.agent_loop_guard.max_runs_per_subject_per_hour

Section titled “policies.agent_loop_guard.max_runs_per_subject_per_hour”

Maximum runs per hour, triggered by agents or automation, of one person on one ticket, pull request or document, counted across the person’s work items on it (an item without one counts alone). Humans are never limited.

  • Type: integer
  • Optional
  • Default: 12
  • Minimum 1

Thresholds that slow down work as the LLM usage limit approaches.

  • Type: object
  • Optional
  • Default: {"defer_scheduled_at":0.85,"pause_automatic_at":0.95}

Fraction of the usage limit at which scheduled work is deferred.

  • Type: number
  • Optional
  • Default: 0.85
  • Minimum 0
  • Maximum 1

Fraction of the usage limit at which all automatic work pauses.

  • Type: number
  • Optional
  • Default: 0.95
  • Minimum 0
  • Maximum 1

Groups of people who use one LLM subscription, as lists of handles. A usage report from any member applies to all of them.

  • Type: list of list of string
  • Optional
  • Type: list of string
  • Optional
  • Minimum items 2
  • Type: string
  • Optional
  • Minimum length 1

The reactions that show people their message or comment was picked up.

  • Type: object
  • Optional
  • Default: {"chat":true,"vcs":true}

React with eyes to a chat message from a trusted person when the agent has seen it. Default on.

  • Type: boolean
  • Optional
  • Default: true

React with eyes to each pull request comment the agent is about to answer, when its round starts. Needs a vcs adapter with vcs.reactions. Default on.

  • Type: boolean
  • Optional
  • Default: true

How agents act on feedback from trusted people beyond the first round.

  • Type: object
  • Optional
  • Default: {"follow_up_round":true}

Start another round when feedback arrived after the agent was offered its work. Default on.

  • Type: boolean
  • Optional
  • Default: true

What happens to a ticket when an agent hands its work back.

  • Type: object
  • Optional
  • Default: {"blocked_notify":"pm","fallback":"first_human"}

Who tells the requester about blocked work that did not come from chat: agent has the blocked agent tell them itself, in its own direct message; pm leaves it to the team’s PM, who gives the ticket to the requester, saying what is needed, only when it cannot unblock it, and the blocked agent sends nothing. Either way a blocked ticket goes to the PM to unblock when the team has one; this only decides who sends the chat message. Without a PM role the agent always does. The office never posts to people. Default pm.

  • Type: string
  • Optional
  • Default: pm
  • Allowed values: pm, agent

Who stands in when a ticket has no known requester: the first human in humans with a tracker identity, or none to skip. Default first_human.

  • Type: string
  • Optional
  • Default: first_human
  • Allowed values: first_human, none

How tickets and pull requests relate.

  • Type: object
  • Optional
  • Default: {"prs_per_ticket":"one"}

How many pull requests a ticket may have. one: ost pr open refuses a second one for a ticket; many: several are allowed. Either way the ticket moves to done when its last open pull request merges into the default branch. Default one.

  • Type: string
  • Optional
  • Default: one
  • Allowed values: one, many

Have an agent tell a human in a direct message in chat when work lands on them: a ticket it hands back to them for review, a blocked ticket given to them (a PM that cannot unblock it, for example), or a pull request it opens for their review. The message links the ticket and the pull requests and says, in a line or two from the hand-back, what is needed. One agent’s messages to one human are batched (pipeline.notify.debounce_seconds). A human with no identities.chat is sent nothing, and the office logs it. Default on.

  • Type: boolean
  • Optional
  • Default: true

Let an agent with nothing queued or running start its next ready ticket: assigned to it, in the ready status, highest tracker priority first, then the one ready the longest. Counts as automatic work. Default on.

  • Type: boolean
  • Optional
  • Default: true

How a failing work item is retried: exponential backoff, then blocked.

  • Type: object
  • Optional
  • Default: {"base_minutes":1,"cap_minutes":30,"max_failures":3}

Wait after the first failed run of a work item; doubles with each failure.

  • Type: integer
  • Optional
  • Default: 1
  • Minimum 1

Longest wait between two attempts at a failing work item.

  • Type: integer
  • Optional
  • Default: 30
  • Minimum 1

Consecutive failed runs after which the work item is blocked.

  • Type: integer
  • Optional
  • Default: 3
  • Minimum 1

Agents merging their own approved pull requests, each merge their decision, woken when a pull request may be ready (opt-in).

  • Type: object
  • Optional
  • Default: {"on_approval":false,"approvers":["humans"]}

Let agents merge their own approved pull requests. When an agent’s pull request may be ready to merge (an allowed approver approves it with its checks green, its checks turn green while it is approved, or the pull request it was stacked on merges), the office wakes its author to decide: merge it with ost pr merge, wait, or coordinate first. ost pr merge checks the approvals and the required checks, and where the repository has a merge queue merging means joining it. Off by default: no one is woken to merge, ost pr merge refuses, and people merge. Needs a vcs adapter with vcs.merge.

  • Type: boolean
  • Optional
  • Default: false

Who may approve a merge with ost pr merge: humans (the people in humans, or anyone with write access when humans is omitted), human: (one human, by vcs identity), role: (the agent playing a catalog role) or a handle (an agent, or a human by vcs login). Default humans.

  • Type: list of string
  • Optional
  • Default: ["humans"]
  • Minimum items 1
  • Type: string
  • Optional
  • Must match ^(humans|human:\S+|role:[a-z][a-z0-9-]*|[A-Za-z0-9][A-Za-z0-9._[\]-]*)$

How ost pr merge merges: queue (the host’s merge queue), merge or squash. When omitted, outstaff uses what the repository has: its merge queue, else a method its settings allow.

  • Type: string
  • Optional
  • Allowed values: queue, merge, squash

Names of the repos (from repos) whose pull requests agents may merge, and are woken to merge. Default: every repo an agent can write to.

  • Type: list of string
  • Optional
  • Minimum items 1
  • Type: string
  • Optional
  • Minimum length 1

The checks that run on a pull request’s merge commit in the default branch, such as a deploy. A ticket closes only once they pass; when one fails, the author is woken with its log.

  • Type: object
  • Optional
  • Default: {"wait_for_start_minutes":5,"timeout_minutes":120,"settle_minutes":2}

policies.merge_checks.wait_for_start_minutes

Section titled “policies.merge_checks.wait_for_start_minutes”

Minutes the office waits for a check to appear on a merge commit. With none by then, the merge counts as passed and its ticket can close. Fractions are allowed. Default 5.

  • Type: number
  • Optional
  • Default: 5
  • Maximum 1440

Minutes after the merge after which a check still running on the merge commit counts as failed, naming that check. Fractions are allowed. Default 120.

  • Type: number
  • Optional
  • Default: 120
  • Maximum 10080

Minutes the checks on a merge commit must stay finished, with none failed and no new one appearing, before the merge counts as passed, so a workflow that starts after the first ones finish is still waited for. Fractions are allowed. Default 2.

  • Type: number
  • Optional
  • Default: 2
  • Minimum 0
  • Maximum 1440

How agents write chat messages.

  • Type: object
  • Optional
  • Default: {"max_lines":3,"always_link":true,"omit":["ci","mergeability","hashes"]}

Guidance for agents: keep chat replies to about this many lines. It is a hard limit only for the office’s own automatic notices (status lines, run notifications). An agent’s reply is never cut; one over a high safety cap is split into several messages.

  • Type: integer
  • Optional
  • Default: 3
  • Minimum 1
  • Maximum 20

Link tickets, pull requests and documents instead of mentioning bare ids.

  • Type: boolean
  • Optional
  • Default: true

Details left out of chat messages.

  • Type: list of string
  • Optional
  • Default: ["ci","mergeability","hashes"]
  • Allowed values: ci, mergeability, hashes, file_lists
  • Type: string
  • Optional
  • Allowed values: ci, mergeability, hashes, file_lists

What design roles may use.

  • Type: object
  • Optional
  • Default: {"canvas":true}

Let roles that declare the design.canvas capability use Claude’s Artifact tools (the Design canvas), and roles that declare design.canvas.read read those canvases. Needs the claude-agent-sdk runtime signed in with a Claude account. Default on; it does nothing for a role without either capability.

  • Type: boolean
  • Optional
  • Default: true

How agents take chat messages, and what they show in chat.

  • Type: object
  • Optional
  • Default: {"parallel_sessions":2,"profile":true}

How many chat sessions an agent runs at once, beside its active work item. A message beyond that waits for a free session.

  • Type: integer
  • Optional
  • Default: 2
  • Minimum 1
  • Maximum 10

Publish the agent’s profile in chat: role, status, and current work grouped by ticket or pull request. Needs a chat adapter with chat.agentProfile. Default on.

  • Type: boolean
  • Optional
  • Default: true

Command rules for this team’s own tools, on top of the built-in and toolset rules.

  • Type: object
  • Optional

Commands agents may run of a program. Everything runs by default; once a rule here names a program, the program runs only what such rules allow, and built-in default denies for it (such as kubectl apply) are lifted.

  • Type: list of object
  • Optional

A command rule.

  • Type: object
  • Optional

Program name, for example make. Git is governed by repository grants.

  • Type: string
  • Required
  • Minimum length 1
  • Must match ^[^\s/]+$

Leading positional words, for example [“pr”, “view”].

  • Type: list of string
  • Optional
  • Minimum items 1
  • Type: string
  • Optional
  • Minimum length 1

Every condition must hold for the rule to apply.

  • Type: list of any
  • Optional
  • Minimum items 1

A condition on the command arguments.

  • Type: any
  • Optional

Why the rule exists; shown when it decides a call.

  • Type: string
  • Required
  • Minimum length 1

The working repository must have at least this grant.

  • Type: string
  • Optional
  • Allowed values: read, write

Commands agents may never run. Deny always wins over allow.

  • Type: list of object
  • Optional

A command rule.

  • Type: object
  • Optional

Program name, for example make. Git is governed by repository grants.

  • Type: string
  • Required
  • Minimum length 1
  • Must match ^[^\s/]+$

Leading positional words, for example [“pr”, “view”].

  • Type: list of string
  • Optional
  • Minimum items 1
  • Type: string
  • Optional
  • Minimum length 1

Every condition must hold for the rule to apply.

  • Type: list of any
  • Optional
  • Minimum items 1

A condition on the command arguments.

  • Type: any
  • Optional

Why the rule exists; shown when it decides a call.

  • Type: string
  • Required
  • Minimum length 1

The working repository must have at least this grant.

  • Type: string
  • Optional
  • Allowed values: read, write

Event pipeline policies of the team’s own, which run after the built-in ones: each a module of the team’s repository or an npm package that exports policy (or a policies list). They run in the office process, as trusted as this repository. ost validate and the office load and check each one.

  • Type: list of object
  • Optional

A custom policy to load: module or package, and its settings.

  • Type: object
  • Optional

Path of the module, relative to this file, for example ./policies/release-freeze.ts.

  • Type: string
  • Required
  • Minimum length 1

Values the policy reads as ctx.settings; what it accepts is up to the policy.

  • Type: map
  • Optional

Name of an installed npm package, for example @acme/outstaff-policy-oncall.

  • Type: string
  • Required
  • Minimum length 1

Where agents keep their memory: the lasting lessons and preferences they note.

  • Type: object
  • Optional

Where agents keep their notes (ost note): volume, files in memory/ on each agent’s home volume, which must then be backed up; or knowledge, a page per agent in the knowledge integration, which must provide knowledge.notes.

  • Type: string
  • Optional
  • Default: volume
  • Allowed values: volume, knowledge

Tokens and cost of agent work, per run and per ticket.

  • Type: object
  • Optional

Record the tokens and cost of every run and total them per ticket, sub-tickets rolled up into their parent. The cost is what the runs would cost at API prices (API-equivalent), not what a subscription bills. Default on.

  • Type: boolean
  • Optional
  • Default: true

Show each ticket’s totals in two custom fields of the tracker, “Agent tokens” and “Agent cost, USD (API-equivalent)”, written by the agent whose run it was. Needs a tracker with tracker.fields. Off keeps the totals in the office only. Default on.

  • Type: boolean
  • Optional
  • Default: true