Open Agent Toolkit

Providers

Provider Quick Browse

  • Project: .agents/skills -> .claude/skills, .agents/agents -> .claude/agents, .agents/rules -> .claude/rules
  • User: ~/.agents/skills -> ~/.claude/skills, ~/.agents/agents -> ~/.claude/agents
  • Rule files stay .md and are rendered with Claude-compatible frontmatter when needed
  • Managed effort-pinned phase implementers and reviewers use the exact generated candidate returned as providers.claude.dispatchArgs.variant; its frontmatter carries model and effort because Agent has no per-call effort field. Legacy model-only candidates retain providers.claude.dispatchArgs.model, and any model supplied alongside a variant must match its definition.
  • Generated names preserve the full normalized configured model ID after the provider token. A versioned ID such as claude-opus-5-5 therefore produces the deterministic slug oat-reviewer-claude-claude-opus-5-5-high. This doubled claude- is the current managed-role contract, not a request to rename existing roles.
  • Project variants live under .claude/agents/; user variants live under ~/.claude/agents/. Sync removes stale managed variants for the reconciled owner while preserving base roles and unmanaged agents.
  • Base oat-phase-implementer and oat-reviewer roles sync like any other canonical agent at both scopes, so legacy model-only dispatch and base-role fallback resolve after a pack moves to user scope.
  • Claude's official subagent contract says existing agent directories are watched and changes load within seconds. It describes a conditional restart for the first agent added to a directory that was absent when the session started, for agents added through --add-dir, and when Claude starts with --disable-slash-commands. OAT cannot observe those session-start and launch-mode facts. After a successful provider-visible file change, the generic OAT repository policy therefore conservatively advises starting a new provider session; it does not claim that Claude hot-reloaded the file or that the application process must restart. The provider semantics were verified against Claude Code subagent documentation on 2026-08-31.

Managed dispatch views

Reusable ordered candidate ladders live in workflow.dispatchCeiling.providers. The project or phase named ceiling is only a maximum over those candidates; it does not select one permanent model family for the project.

Adopt the complete ladder into an explicit owning config scope before sync:

oat config adopt dispatch-matrix --shared
oat config adopt dispatch-matrix --local
oat config adopt dispatch-matrix --user

These commands replace bundled cells in the chosen scope and warn about replacements. Add --dry-run to preview or --keep-existing to fill only missing cells.

Project-config candidates materialize into the tracked, version-controlled project .codex and .cursor views. User-config candidates materialize under ~/.codex and ~/.cursor. OAT does not auto-ignore project output or create its Git commit; the team owns that repository change.

At implementation time, the root passes the recorded named maximum through invocation-only --ceiling-tier, resolves one exact candidate per phase, and dispatches one phase implementer. Codex first attempts the resolver-returned materialized role as the native agent_type. The launcher records the target, model axis, and effort axis from that resolved payload; child self-report is not provenance and cannot replace those values. Only an explicit pre-start native role-selection rejection permits another target-preserving route. An accepted child, including one that later returns BLOCKED or lacks telemetry, is a task outcome rather than a fallback signal. Claude binds the exact generated variant for effort-pinned targets or the exact model argument for legacy targets. Cursor launches the exact native variant. A missing or unselectable managed target blocks rather than falling back to the root target or a base role.

Post-launch runtime observation

Runtime observation is a separate, optional layer from the configured invocation above. It never changes launch, fallback, policy, ceiling, role, authority, or any selector: it only records what a provider said about its own child, so a configured selection and an observed identity stay independently readable.

Codex reports child lineage, role, model, and effort through its session and turn metadata. It reports no service tier: the parser accepts one for forward compatibility, but no captured rollout carries the field. Claude reports role, model, effort, and service tier from its on-disk transcript metadata, and lineage only as root-or-child: it emits no depth field, so a subagent turn is recorded as depth-unknown rather than given an invented depth. Claude's role comes from the same class of bounded role identifier Codex records, and is reported only on the subagent turns that carry one. Cursor exposes no metadata channel and stays explicitly not-reported.

not-exposed is reserved for an axis a provider genuinely does not have. It is not a stand-in for an axis that simply went unreported on a given run, and it is never written in place of a value the provider did report.

Observation is metadata-only. Parsers select entries by type and never read conversation content, and raw provider output is projected through the owning parser's allowlist before validation, so instruction text, conversation bodies, and working directories are dropped rather than merely ignored. A missing, unparseable, or uncorrelated observation is not-reported, never a copy of the requested arguments or the materialized pin. An observed mismatch is evidence for a human to read; it is not a fallback trigger and cannot authorize replacement or retry.

Materialization, refresh, and visibility

OAT reports three separate facts rather than collapsing them into “available”:

  1. Materialization says whether the canonical asset's provider output was changed, current, missing, failed, unsupported, or unknown.
  2. Catalog refresh policy is provider- and content-specific. A policy is live, manual-refresh, restart-required, or unknown, with its source and verification date.
  3. Runtime visibility says whether the active provider catalog was actually observed. oat sync, oat status, oat doctor, and install-triggered sync do not query a running provider session, so they report visibility as not-reported or unknown, never visible.

After a successful provider-visible file change, oat sync conservatively advises starting a new provider session so the provider has an opportunity to load the changed asset. This repository decision was approved on 2026-08-31 and is recorded in the active project's implementation record. It is safety guidance, not a provider hot-reload guarantee, an instruction to restart the application process, or proof that the new session loaded or exposed the asset. The compatibility schema reports this session boundary as restart-required; with repository-decision provenance, that state means “start a new provider session,” not “restart the application.” No advice is emitted for current/no-op, planned-only, failed, missing, inactive, or unsupported materialization.

A truthful provider/content-specific policy takes precedence over this generic repository decision. Claude's documented behavior remains conditional on session-start and launch-mode facts that OAT cannot observe, so OAT does not claim those conditions were met; the conservative new-session advice still applies after a successful file change. Unsupported capabilities retain an unknown policy rather than inheriting advice. A current file with no current-session catalog probe is still not proof of provider visibility.

Scope rules

  • Project scope: skills + agents + rules
  • User scope: skills plus capability-supported ordinary agents (provider mappings vary by adapter)
  • The two bundled managed roles separately participate in Codex, Cursor, and Claude extension expansion for user-owned targets. Only Codex renders the base roles itself; Claude and Cursor receive base roles through ordinary agent sync with generated variants alongside
  • Rules are project-scoped only in this release
  • Codex user-scope sync materializes user-config custom roles under ~/.codex; project-config and supported-catalogue output remains project-scoped and version controlled
  • Cursor user-scope sync materializes user-config variants under ~/.cursor/agents; project-config and supported-catalogue output remains project-scoped and version controlled

Canonical rule frontmatter

Canonical rules in .agents/rules/*.md declare activation as one of always, glob, agent-requested, or manual; globs is valid only with activation: glob.

Third-party installers sometimes write Cursor-style rules straight into .agents/rules/ (for example argent init, reported in GitHub issue #316). OAT accepts that shape through one narrow alias:

  • alwaysApply: true with no activation is read as activation: always.
  • Under that alias a null or empty globs value is ignored, and a non-empty globs value is an error naming the file, because canonical rules keep globs only for activation: glob.
  • An explicit activation always wins over alwaysApply.
  • alwaysApply: false, or any value other than true, without activation stays an activation error that names the file.

Every canonical rule parse error names the repository-relative rule file.

Adoption model

  • Stray adoption is available in oat init and oat status.
  • Adoption reconciles canonical plus the adopted provider first.
  • Native-read Cursor skill adoption moves the provider-local skill into .agents/skills without recreating a .cursor/skills view or manifest entry.
  • Choosing Keep Cursor-only leaves the skill in place and records its exact normalized path in the project or user sync config.
  • Native-read Copilot skill adoption moves a legacy provider-local skill into the matching canonical .agents/skills directory without recreating a .github/skills or ~/.copilot/skills view or manifest entry.
  • Choosing Keep Copilot-only leaves the skill in place and records its exact normalized path in the project or user sync config.
  • Rule adoption normalizes provider filenames back to canonical .agents/rules/*.md entries before cross-provider fanout.
  • Cross-provider fanout is explicit via oat sync --scope all.

Provider mutation safety

The generic sync engine validates provider destinations for every operation that creates or updates a symlink, creates or updates a copy, or removes a managed provider path. The same guard applies across provider adapters; it is not Claude-specific.

Validation runs at three boundaries:

  1. During planning, before a provider operation is classified.
  2. Across the complete mutating plan before apply starts, so an already-unsafe later entry cannot allow earlier provider or manifest mutations.
  3. Immediately before each entry's first filesystem mutation, so ancestry that changes after preflight fails closed.

A mutation is refused when its destination escapes the sync scope, equals the scope root, or has any existing parent that is a symbolic link or not a directory. The final managed destination is excluded from the ancestry walk, so an existing managed symlink can still be updated or removed normally.

Whole-plan preflight refusal leaves provider paths, canonical content, external symlink targets, and manifest state unchanged. If ancestry changes after preflight, the affected entry fails before its first removal or write and does not gain manifest ownership. OAT does not traverse, unlink, or rewrite the unsafe parent.

Reference artifacts

  • .oat/projects/<scope>/<project>/spec.md (FR5)
  • packages/cli/src/providers/**
  • packages/cli/src/providers/shared/adapter.utils.ts

On this page