Provider Interop CLI Scope and Surface
The provider interop CLI in packages/cli manages canonical agent assets under .agents/ and reconciles provider-specific views.
This capability is intentionally independent from OAT workflow artifacts. Teams can adopt provider interoperability usage (status, sync, providers ...) plus optional project-scoped instruction sync integrity checks (instructions validate/sync) without using discovery/spec/design/plan/implement project workflows.
Scope
- Canonical directories:
.agents/skills,.agents/agents,.agents/rules - Managed provider views:
.claude/*,.cursor/*,.github/*,.copilot/*,.codex/*(where applicable) - Native-read mappings use canonical
.agents/*directly without mirrored provider directories. Cursor and Copilot skills, Gemini skills and agents, and Codex canonical mappings use this model. - Cursor's
.cursor/skillsand~/.cursor/skillsdirectories are provider-local extension and adoption surfaces, not managed output directories. - Copilot's legacy
.github/skillsand~/.copilot/skillsdirectories are adoption sources, not managed output directories. Copilot agents and project rules still use.github/agents,~/.copilot/agents, and.github/instructionsprovider views. - Manifest tracking:
.oat/sync/manifest.json(project) and~/.oat/sync/manifest.json(user) - Canonical skills and agents installed by OAT tool packs exist at both scopes:
.agents/skills,.agents/agentsfor project scope, and~/.agents/skills,~/.agents/agentsfor user scope. Every reusable pack defaults to user scope on a fresh install, so user-scope canonical content is the common case rather than the exception.
Rules are currently project-scoped canonical content. Unlike skills and agents, synced rule files for Claude, Cursor, and Copilot are rendered copies with provider-specific frontmatter and filename extensions.
Design principles
- Mutate by default;
--dry-runto preview - Explicit
--dry-runfor safe preview of mutations - Scoped destructive actions only for manifest-tracked entries
- Cross-provider compatibility via adapters
- Native-read assets stay canonical while provider-local adoption sources remain discoverable independently
- Obsolete managed mappings are deleted only when their provider paths are verified clean; changed or unverified paths are preserved and detached from manifest ownership
- Canonical
.agents/agentsis source of truth for subagents; provider views are derived - Canonical
.agents/rulesis source of truth for rules; provider rule files are derived rendered copies - Each scope syncs independently. When the same canonical asset exists at both project and user scope, OAT reports the duplication with both paths and versions and does not infer which copy a provider executes; resolve it explicitly with
oat tools migrate - Pack removal and migration drive a symmetric removal sync: the exact canonical paths that were removed are pruned from provider views in that scope only, and only after the canonical source is confirmed absent
- A successful provider write proves materialization only. Catalog refresh policy and current-session visibility are separate evidence; without a provider catalog observation, OAT does not claim the asset is visible.
Implemented command surface
oat statusoat syncoat providers listoat providers inspectoat providers setoat providers codex materializeoat project dispatch record(project-aware dispatch evidence only; never a provider launcher)
Adjacent CLI commands (commonly used with provider interop)
oat init(bootstrap canonical structure and sync config) — see../cli-utilities/bootstrap.mdoat tools ...(install/update/remove/migrate/list/inspect tools) — see../cli-utilities/tool-packs.mdoat doctor(environment + skill-version diagnostics) — see../reference/cli-reference.md
Provider enablement model
- Project provider enablement is stored in
.oat/sync/config.json(providers.<name>.enabled). - User provider enablement is stored in
~/.oat/sync/config.json.oat providers set --scope user --enabled claudeandoat providers set --scope user --disabled claudeupdate this canonical user config while preserving unrelated fields. oat providers listandoat providers inspectshow configuration-owned activation separately from filesystem detection, plus registered scope/content capability, projection modes, native reads, materialization, and visibility evidence.oat init --scope project(interactive) prompts for supported providers and persists explicit true/false values.oat sync --scope projectuses config-aware provider activation and can prompt to remediate detected mismatches.- Cursor provider enablement still controls agents, rules, migration discovery, and legacy cleanup even though Cursor reads canonical skills without a generated skill view.
- Copilot provider enablement still controls agents, project rules, migration discovery, and legacy cleanup even though Copilot reads canonical skills without a generated skill view.
- Codex project-scope subagent sync writes
.codex/config.tomland.codex/agents/*.tomlat command layer after path-mapping sync. Every generated project Codex variant and registration is repository-owned, version-controlled provider output. OAT provides no automatic ignore mechanism for this project output; collaborators review and commit it like other project configuration. - Default Codex execution requires
root (0) → phase implementer (1). Sync and direct materialization continue to apply anagents.max_depthfloor of2as optional nested-work capability without lowering a higher target value. A project write may read a higher lower-precedence user value and preserves it in project configuration; it writes only project.codex/config.toml. User scope writes only~/.codex/config.tomland does not read or change project configuration. - Missing depth or depth
1does not block default phase execution. Invalid values or explicit values below1fail managed implementation preflight.oat doctorreports whether optional depth-two nesting is available and gives a scope-specific repair when the configured value is unusable. - Codex aggregate config drift is reported via sync/status extension metadata (
aggregateConfigHash); it is not persisted as a separate manifest schema entry. - Codex user-config materialization writes user-owned implementer and reviewer roles under the user provider directory,
~/.codex; it does not write those roles into the repository.
Provider refresh evidence
Refresh advice is emitted only for a successful, relevant current-run change.
For every supported provider-visible capability without a stronger sourced
policy, the registry records the OAT repository decision approved on
2026-08-31: start a new provider session so it has an opportunity to load the
changed asset. This is conservative safety guidance, not a provider hot-reload
guarantee, an application-process restart requirement, or proof that the new
session loaded or exposed the asset. Current/no-op, planned-only, failed,
missing, inactive, and unsupported materialization receive no such advice;
unsupported capabilities keep an unknown policy.
The compatibility schema names this session boundary restart-required. When
its provenance is repository-decision, the recovery text means “start a new
provider session,” not “restart the application.”
A truthful provider/content-specific policy takes precedence over the generic
repository decision. The official Claude Code subagent contract, verified on
2026-08-31, says existing agent directories are watched and changes load within
seconds. It describes a conditional restart for the first agent added to a
directory absent at session start, for agents added through --add-dir, and
when Claude starts with --disable-slash-commands. OAT cannot observe those
runtime conditions and does not claim they occurred; it applies only the
generic new-session guidance after a successful file change.
oat status, oat doctor, and oat init expose that their running-provider
catalog observation is not-reported. They inspect filesystem/configuration
state, not the provider's active catalog. Only an actual current-session probe
can establish visible.
Codex managed dispatch
For managed Codex work, the resolver-returned materialized role is attempted as
the native agent_type first. The launcher owns the resulting target, model,
and reasoning-effort provenance, derived from the resolved candidate and
compiled invocation payload; worker output cannot populate or overwrite it.
A fresh pinned child is allowed only after explicit pre-start native
role-selection rejection. Missing runtime telemetry, missing self-report, or a
child accepted by the native route that later returns BLOCKED are not
role-selection rejection and do not permit fallback.
Project workflows construct and redact the complete dispatch payload before
the native call, then record its accepted or blocked-before-start result in
the project's run record; persisting it under the project's dispatch/
directory is optional and off by default. The generic
record remains provider-neutral. OAT-specific canonical role, rejection,
fallback, and runtime facts live only under its oat namespace. A qualifying
fallback is a fresh request that preserves exact target and controls and is
explicitly labeled an approximation; timeout, refusal after acceptance,
runtime mismatch, malformed output, and missing telemetry never authorize it.
Non-interop namespaces in the same CLI
oat project new <name>(workflow/project scaffolding)oat instructions validate/oat instructions sync(AGENTS.md/CLAUDE.md pointer, symlink, or copy integrity plus Claude-only adoption)oat internal validate-oat-skills(internal maintenance)
Reference artifacts
.oat/projects/<scope>/<project>/spec.md.oat/projects/<scope>/<project>/design.md.oat/projects/<scope>/<project>/plan.md.oat/projects/<scope>/<project>/implementation.md