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
.mdand are rendered with Claude-compatible frontmatter when needed - Managed phase implementers and optional nested workers use the exact configured candidate returned as
providers.claude.dispatchArgs.model; OAT passes that value as the actual Agentmodel - 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 --userProject-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 model argument described above. 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”:
- Materialization says whether the canonical asset's provider output was changed, current, missing, failed, unsupported, or unknown.
- Catalog refresh policy is provider- and content-specific. A policy is
live,manual-refresh,restart-required, orunknown, with its source and verification date. - 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 asnot-reportedorunknown, nevervisible.
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 and Cursor extension expansion for user-owned targets
- 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
Adoption model
- Stray adoption is available in
oat initandoat status. - Adoption reconciles canonical plus the adopted provider first.
- Native-read Cursor skill adoption moves the provider-local skill into
.agents/skillswithout recreating a.cursor/skillsview 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/skillsdirectory without recreating a.github/skillsor~/.copilot/skillsview 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/*.mdentries 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:
- During planning, before a provider operation is classified.
- Across the complete mutating plan before apply starts, so an already-unsafe later entry cannot allow earlier provider or manifest mutations.
- 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