@open-agent-toolkit/cli 0.1.73 → 0.1.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/config/dispatch-matrix-recommendation.json +13 -17
- package/assets/docs/cli-utilities/configuration.md +53 -72
- package/assets/docs/cli-utilities/workflow-gates.md +38 -2
- package/assets/docs/provider-sync/commands.md +26 -0
- package/assets/docs/provider-sync/config.md +17 -6
- package/assets/docs/provider-sync/index.md +17 -5
- package/assets/docs/provider-sync/manifest-and-drift.md +39 -1
- package/assets/docs/provider-sync/providers.md +23 -19
- package/assets/docs/provider-sync/scope-and-surface.md +5 -1
- package/assets/docs/reference/file-locations.md +9 -3
- package/assets/docs/reference/oat-directory-structure.md +11 -3
- package/assets/docs/reference/troubleshooting.md +11 -0
- package/assets/docs/workflows/projects/artifacts.md +1 -1
- package/assets/docs/workflows/projects/dispatch-ceiling.md +29 -33
- package/assets/docs/workflows/projects/implementation-execution.md +7 -4
- package/assets/docs/workflows/projects/lifecycle.md +4 -3
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/create-agnostic-skill/SKILL.md +1 -1
- package/assets/skills/create-agnostic-skill/references/docs/skills-guide.md +24 -15
- package/assets/skills/oat-agent-instructions-analyze/references/docs/provider-reference.md +9 -3
- package/assets/skills/oat-agent-instructions-apply/references/docs/provider-reference.md +9 -3
- package/assets/skills/oat-dispatch-subagents/SKILL.md +1 -1
- package/assets/skills/oat-dispatch-subagents/references/provider-cursor.md +27 -15
- package/assets/skills/oat-project-autonomous/SKILL.md +1 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +17 -15
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +15 -9
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/references/phase-execution.md +11 -5
- package/assets/skills/oat-project-import-plan/SKILL.md +30 -8
- package/assets/skills/oat-project-plan/SKILL.md +30 -8
- package/assets/skills/oat-project-plan-writing/SKILL.md +12 -9
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-quick-start/SKILL.md +30 -8
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-review-provide/SKILL.md +19 -11
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +27 -4
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +55 -0
- package/dist/commands/doctor/index.d.ts +2 -1
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +37 -1
- package/dist/commands/gate/index.d.ts +1 -1
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +35 -3
- package/dist/commands/init/index.d.ts +7 -3
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +129 -38
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +17 -9
- package/dist/commands/remove/skill/remove-skill.d.ts +2 -0
- package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
- package/dist/commands/remove/skill/remove-skill.js +20 -2
- package/dist/commands/shared/adopt-stray.d.ts.map +1 -1
- package/dist/commands/shared/adopt-stray.js +3 -0
- package/dist/commands/shared/codex-strays.d.ts +9 -0
- package/dist/commands/shared/codex-strays.d.ts.map +1 -1
- package/dist/commands/shared/codex-strays.js +4 -0
- package/dist/commands/shared/cursor-skill-disposition.d.ts +17 -0
- package/dist/commands/shared/cursor-skill-disposition.d.ts.map +1 -0
- package/dist/commands/shared/cursor-skill-disposition.js +41 -0
- package/dist/commands/status/index.d.ts +17 -5
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +151 -47
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +50 -24
- package/dist/commands/sync/dry-run.d.ts.map +1 -1
- package/dist/commands/sync/dry-run.js +31 -18
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +34 -25
- package/dist/commands/sync/sync.types.d.ts +26 -11
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.js +3 -2
- package/dist/config/oat-config.d.ts +0 -1
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +26 -23
- package/dist/config/sync-config.d.ts +6 -2
- package/dist/config/sync-config.d.ts.map +1 -1
- package/dist/config/sync-config.js +18 -6
- package/dist/config/user-sync-config.d.ts +11 -0
- package/dist/config/user-sync-config.d.ts.map +1 -0
- package/dist/config/user-sync-config.js +61 -0
- package/dist/drift/strays.d.ts +1 -1
- package/dist/drift/strays.d.ts.map +1 -1
- package/dist/drift/strays.js +2 -1
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +154 -4
- package/dist/engine/engine.types.d.ts +2 -2
- package/dist/engine/engine.types.d.ts.map +1 -1
- package/dist/engine/engine.types.js +1 -0
- package/dist/engine/execute-plan.d.ts.map +1 -1
- package/dist/engine/execute-plan.js +4 -0
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +1 -1
- package/dist/engine/scanner.d.ts +3 -1
- package/dist/engine/scanner.d.ts.map +1 -1
- package/dist/engine/scanner.js +4 -2
- package/dist/manifest/manifest.types.d.ts +12 -12
- package/dist/providers/ceiling/registry.d.ts +2 -0
- package/dist/providers/ceiling/registry.d.ts.map +1 -1
- package/dist/providers/ceiling/registry.js +20 -4
- package/dist/providers/codex/codec/sync-extension.d.ts +11 -10
- package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/codex/codec/sync-extension.js +42 -14
- package/dist/providers/cursor/codec/catalog.d.ts +18 -0
- package/dist/providers/cursor/codec/catalog.d.ts.map +1 -0
- package/dist/providers/cursor/codec/catalog.js +39 -0
- package/dist/providers/cursor/codec/materialize.d.ts +24 -0
- package/dist/providers/cursor/codec/materialize.d.ts.map +1 -0
- package/dist/providers/cursor/codec/materialize.js +166 -0
- package/dist/providers/cursor/codec/shared.d.ts +14 -0
- package/dist/providers/cursor/codec/shared.d.ts.map +1 -0
- package/dist/providers/cursor/codec/shared.js +76 -0
- package/dist/providers/cursor/codec/sync-extension.d.ts +37 -0
- package/dist/providers/cursor/codec/sync-extension.d.ts.map +1 -0
- package/dist/providers/cursor/codec/sync-extension.js +393 -0
- package/dist/providers/cursor/index.d.ts +3 -0
- package/dist/providers/cursor/index.d.ts.map +1 -1
- package/dist/providers/cursor/index.js +3 -0
- package/dist/providers/cursor/paths.d.ts.map +1 -1
- package/dist/providers/cursor/paths.js +6 -4
- package/dist/providers/identity/availability.d.ts +7 -0
- package/dist/providers/identity/availability.d.ts.map +1 -1
- package/dist/providers/identity/availability.js +23 -0
- package/dist/providers/shared/adapter.types.d.ts +6 -0
- package/dist/providers/shared/adapter.types.d.ts.map +1 -1
- package/dist/providers/shared/adapter.utils.d.ts +2 -1
- package/dist/providers/shared/adapter.utils.d.ts.map +1 -1
- package/dist/providers/shared/adapter.utils.js +29 -6
- package/dist/providers/shared/index.d.ts +2 -0
- package/dist/providers/shared/index.d.ts.map +1 -1
- package/dist/providers/shared/index.js +1 -0
- package/dist/providers/shared/materialization-extension.d.ts +44 -0
- package/dist/providers/shared/materialization-extension.d.ts.map +1 -0
- package/dist/providers/shared/materialization-extension.js +26 -0
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2026-07-
|
|
2
|
+
"version": "2026-07-11.1",
|
|
3
3
|
"providers": {
|
|
4
4
|
"codex": {
|
|
5
5
|
"economy": {
|
|
@@ -101,29 +101,25 @@
|
|
|
101
101
|
"cursor": {
|
|
102
102
|
"economy": {
|
|
103
103
|
"candidates": [
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"gpt-5.6-luna-high"
|
|
104
|
+
"composer-2.5",
|
|
105
|
+
"claude-sonnet-5-high",
|
|
106
|
+
"gpt-5.6-luna-high",
|
|
107
|
+
"gpt-5.6-luna-xhigh"
|
|
107
108
|
]
|
|
108
109
|
},
|
|
109
110
|
"balanced": {
|
|
110
|
-
"candidates": [
|
|
111
|
-
"gpt-5.6-luna-xhigh",
|
|
112
|
-
"gpt-5.6-terra-low",
|
|
113
|
-
"gpt-5.6-terra-medium",
|
|
114
|
-
"gpt-5.6-terra-high",
|
|
115
|
-
"gpt-5.6-terra-xhigh"
|
|
116
|
-
]
|
|
111
|
+
"candidates": ["cursor-grok-4.5-high", "gpt-5.6-terra-high"]
|
|
117
112
|
},
|
|
118
113
|
"high": {
|
|
119
|
-
"candidates": [
|
|
120
|
-
"gpt-5.6-sol-low",
|
|
121
|
-
"gpt-5.6-sol-medium",
|
|
122
|
-
"gpt-5.6-sol-high"
|
|
123
|
-
]
|
|
114
|
+
"candidates": ["gpt-5.6-sol-medium", "gpt-5.6-sol-high"]
|
|
124
115
|
},
|
|
125
116
|
"frontier": {
|
|
126
|
-
"candidates": [
|
|
117
|
+
"candidates": [
|
|
118
|
+
"claude-fable-5-thinking-high",
|
|
119
|
+
"claude-fable-5-thinking-xhigh",
|
|
120
|
+
"gpt-5.6-sol-xhigh",
|
|
121
|
+
"gpt-5.6-sol-max"
|
|
122
|
+
]
|
|
127
123
|
}
|
|
128
124
|
}
|
|
129
125
|
}
|
|
@@ -16,21 +16,23 @@ For the deep file-by-file reference, see:
|
|
|
16
16
|
- [`.oat` Directory Structure](../reference/oat-directory-structure.md)
|
|
17
17
|
- [Sync Config (`.oat/sync/config.json`)](../provider-sync/config.md)
|
|
18
18
|
|
|
19
|
-
## The
|
|
19
|
+
## The five config surfaces
|
|
20
20
|
|
|
21
|
-
| Surface
|
|
22
|
-
|
|
|
23
|
-
| Shared repo config
|
|
24
|
-
| Repo-local config
|
|
25
|
-
| User config
|
|
26
|
-
|
|
|
21
|
+
| Surface | File | Typical contents | Primary CLI surface |
|
|
22
|
+
| ------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
|
|
23
|
+
| Shared repo config | `.oat/config.json` | Repo-wide non-sync settings such as `projects.root`, `git.defaultBranch`, `documentation.*`, `archive.*`, `tools.*`, and shared `workflow.*` defaults | `oat config get/set/list/describe`, `oat gate` |
|
|
24
|
+
| Repo-local config | `.oat/config.local.json` | Per-developer state for this checkout, such as `activeProject`, `lastPausedProject`, repo-local `activeIdea`, and local `workflow.*` overrides | `oat config get/set/list/describe`, `oat gate` |
|
|
25
|
+
| User config | `~/.oat/config.json` | User-level state such as global `activeIdea` fallback and personal `workflow.*` defaults | `oat config describe`, `oat gate` |
|
|
26
|
+
| Project sync config | `.oat/sync/config.json` | Provider enablement, sync strategy, and repo-level known stray settings | `oat providers set`, `oat config describe` |
|
|
27
|
+
| User provider sync config | `~/.oat/sync/config.json` | User sync strategy and personal known provider strays | Provider-sync commands, `oat config describe` |
|
|
27
28
|
|
|
28
29
|
The main split is:
|
|
29
30
|
|
|
30
31
|
- `.oat/config.json` for shared repo behavior
|
|
31
32
|
- `.oat/config.local.json` for local developer state
|
|
32
|
-
- `~/.oat/config.json` for user-scope fallback
|
|
33
|
-
- `.oat/sync/config.json` for provider sync
|
|
33
|
+
- `~/.oat/config.json` for user-scope fallback and workflow state
|
|
34
|
+
- `.oat/sync/config.json` for project provider sync
|
|
35
|
+
- `~/.oat/sync/config.json` for user provider sync
|
|
34
36
|
|
|
35
37
|
## The fastest way to inspect config
|
|
36
38
|
|
|
@@ -232,14 +234,15 @@ values. Planning shows the complete bundled recommendation before asking for
|
|
|
232
234
|
this scope, then rechecks the effective ladder. If explicit cells still leave
|
|
233
235
|
the ladder incomplete, readiness blocks; OAT does not overwrite them.
|
|
234
236
|
|
|
235
|
-
Scope determines ownership and Codex materialization:
|
|
237
|
+
Scope determines ownership and Codex/Cursor materialization:
|
|
236
238
|
|
|
237
239
|
- `--shared` and `--local` are project configuration sources. Their configured
|
|
238
|
-
Codex candidates materialize into the tracked project `.codex`
|
|
240
|
+
Codex and Cursor candidates materialize into the tracked project `.codex`
|
|
241
|
+
and `.cursor` views.
|
|
239
242
|
- `--user` writes reusable personal defaults to `~/.oat/config.json`; those
|
|
240
|
-
|
|
241
|
-
- Active-project sparse candidates also materialize into the tracked
|
|
242
|
-
view.
|
|
243
|
+
candidates materialize under `~/.codex` and `~/.cursor`.
|
|
244
|
+
- Active-project sparse candidates also materialize into the applicable tracked
|
|
245
|
+
project view.
|
|
243
246
|
|
|
244
247
|
Project-generated provider views remain visible to version control. OAT does
|
|
245
248
|
not auto-ignore them. A project-specific active policy or ceiling must not be
|
|
@@ -274,7 +277,7 @@ even when the reusable ladder is user-owned.
|
|
|
274
277
|
},
|
|
275
278
|
"cursor": {
|
|
276
279
|
"balanced": {
|
|
277
|
-
"candidates": ["
|
|
280
|
+
"candidates": ["cursor-grok-4.5-high", "gpt-5.6-terra-high"]
|
|
278
281
|
}
|
|
279
282
|
}
|
|
280
283
|
}
|
|
@@ -285,9 +288,11 @@ even when the reusable ladder is user-owned.
|
|
|
285
288
|
|
|
286
289
|
The bundled recommendation covers 13 Codex model/effort combinations: Luna and
|
|
287
290
|
Terra at `low`, `medium`, `high`, and `xhigh`, plus Sol at those efforts and
|
|
288
|
-
`max`. Claude covers `haiku`, `sonnet`, `opus`, and `fable`. Cursor covers
|
|
289
|
-
|
|
290
|
-
|
|
291
|
+
`max`. Claude covers `haiku`, `sonnet`, `opus`, and `fable`. Cursor covers 12
|
|
292
|
+
verified multi-family flat IDs across Composer, Claude, GPT, and Grok. An
|
|
293
|
+
explicit mapping connects each flat ladder ID to a separate bracket-form
|
|
294
|
+
frontmatter model; configuration and skills never derive or normalize either
|
|
295
|
+
form.
|
|
291
296
|
|
|
292
297
|
The corresponding pinned Codex variant catalogue includes
|
|
293
298
|
`gpt-5.6-luna-high`, `gpt-5.6-terra-xhigh`, `gpt-5.6-sol-high`, and
|
|
@@ -360,7 +365,7 @@ oat project dispatch-ceiling resolve \
|
|
|
360
365
|
--provider cursor \
|
|
361
366
|
--role implementer \
|
|
362
367
|
--ceiling-tier high \
|
|
363
|
-
--candidate-model
|
|
368
|
+
--candidate-model gpt-5.6-sol-high \
|
|
364
369
|
--json
|
|
365
370
|
```
|
|
366
371
|
|
|
@@ -381,11 +386,12 @@ remains compatibility behavior for legacy scalar ceilings and managed
|
|
|
381
386
|
| -------- | ---------------------------------------------------------------------------------------------------- |
|
|
382
387
|
| Codex | `providers.codex.dispatchArgs.variant` as `agent_type`, or a fresh child pinned to model plus effort |
|
|
383
388
|
| Claude | `providers.claude.dispatchArgs.model` as the actual Agent `model` |
|
|
384
|
-
| Cursor | `providers.cursor.dispatchArgs.
|
|
389
|
+
| Cursor | `providers.cursor.dispatchArgs.variant` as the exact native agent type first |
|
|
385
390
|
|
|
386
|
-
Project sync materializes the supported Codex
|
|
387
|
-
project-owned candidate for both `oat-phase-implementer` and
|
|
388
|
-
User sync materializes user-owned candidates under `~/.codex
|
|
391
|
+
Project sync materializes the supported Codex and Cursor catalogues and every
|
|
392
|
+
configured project-owned candidate for both `oat-phase-implementer` and
|
|
393
|
+
`oat-reviewer`. User sync materializes user-owned candidates under `~/.codex`
|
|
394
|
+
and `~/.cursor/agents`:
|
|
389
395
|
|
|
390
396
|
```bash
|
|
391
397
|
oat sync --scope project
|
|
@@ -394,60 +400,31 @@ oat sync --scope all
|
|
|
394
400
|
```
|
|
395
401
|
|
|
396
402
|
Generated roles carry `supported-catalogue`, `project-config`, or `user-config`
|
|
397
|
-
ownership. Cleanup reconciles only the current owner.
|
|
398
|
-
|
|
399
|
-
correctness does not require provider restart or hot reload.
|
|
403
|
+
ownership. Cleanup reconciles only the current owner. Cursor's mapping registry
|
|
404
|
+
rejects unknown flat IDs instead of writing unverified frontmatter.
|
|
400
405
|
|
|
401
406
|
Reviewer resolution uses the final candidate at the configured review ceiling.
|
|
402
|
-
Codex
|
|
403
|
-
exact model argument. Timeout retries preserve the same complete
|
|
404
|
-
lower reviewer candidate requires a separate reviewed contract.
|
|
407
|
+
Codex and Cursor select exact native reviewer variants; Claude passes the
|
|
408
|
+
resolver's exact model argument. Timeout retries preserve the same complete
|
|
409
|
+
payload. A lower reviewer candidate requires a separate reviewed contract.
|
|
405
410
|
|
|
406
411
|
Tier 2 remains target-preserving. Inline review is permitted only when the host
|
|
407
412
|
has verified equivalent current-host controls for explicit inherit,
|
|
408
413
|
managed-uncapped, or base-role behavior. Capped managed reviews still require
|
|
409
414
|
the exact registered role, pinned child, or resolver-returned model argument.
|
|
410
415
|
|
|
411
|
-
### Cursor
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
establish `unknown-value`. Neither result identifies the backend runtime model:
|
|
424
|
-
`runtimeIdentity` remains `not-reported` unless trusted Cursor telemetry or
|
|
425
|
-
Cursor support confirms it. Parent prose and broad catalog presence are
|
|
426
|
-
diagnostic-only, so OAT preserves `unvalidated` when launcher evidence is
|
|
427
|
-
absent instead of inferring capability from candidate spelling.
|
|
428
|
-
|
|
429
|
-
The [dated GPT-5.6 Cursor verification evidence](https://github.com/voxmedia/open-agent-toolkit/blob/main/.oat/repo/reference/project-summaries/20260711-cursor-gpt-5-6-subagent-verification.md)
|
|
430
|
-
preserves the original text-mode pass and a versioned stream-JSON second pass.
|
|
431
|
-
The second pass ran a dynamic positive control and deliberate invalid control
|
|
432
|
-
before candidates. Both parent runs completed without a Task event, making the
|
|
433
|
-
controls inconclusive; the stop rule therefore executed zero of the 13
|
|
434
|
-
recommended candidates and did not execute exploratory
|
|
435
|
-
`gpt-5.6-sol-high-fast`. The recommendation remains unchanged and candidate
|
|
436
|
-
eligibility remains unresolved.
|
|
437
|
-
|
|
438
|
-
The tracked artifact's structured second-pass block contains only allowlisted
|
|
439
|
-
event structure, derived outcomes, sanitized auth-presence context, and
|
|
440
|
-
non-reversible identifier hashes. Exact request/session/tool-call IDs and
|
|
441
|
-
credential-redacted unprojected streams from that pass stay under gitignored
|
|
442
|
-
`.oat/projects/local/` storage for possible Cursor support diagnosis.
|
|
443
|
-
|
|
444
|
-
The same public artifact intentionally retains the sanitized historical v1
|
|
445
|
-
text-mode record for provenance. That older section includes command arguments
|
|
446
|
-
and prompts, stdout and stderr, exit and duration data, and capture-environment
|
|
447
|
-
details such as user-specific binary paths; it is not limited to the structured
|
|
448
|
-
second-pass allowlist. Re-run after a Cursor client rollout exposes Task in
|
|
449
|
-
headless mode or Cursor support confirms the private requests; review the open
|
|
450
|
-
verification item by 2026-08-08.
|
|
416
|
+
### Cursor availability and evidence
|
|
417
|
+
|
|
418
|
+
`oat doctor` compares configured Cursor flat IDs with the current Cursor
|
|
419
|
+
catalogue and reports availability drift. This check is diagnostic: catalogue
|
|
420
|
+
presence does not prove that a bracket-form definition pin was honored.
|
|
421
|
+
|
|
422
|
+
Each shipped mapping has mapping-specific native-launch evidence, but Cursor
|
|
423
|
+
can silently fallback when account, plan, or administration constraints prevent
|
|
424
|
+
the requested pin. OAT therefore records the selected variant and mapped model
|
|
425
|
+
with launcher-owned `configured` provenance. Runtime identity remains
|
|
426
|
+
`not-reported` unless independently observed; self-report and catalogue
|
|
427
|
+
availability do not upgrade that evidence.
|
|
451
428
|
|
|
452
429
|
### Legacy compatibility
|
|
453
430
|
|
|
@@ -659,9 +636,13 @@ Use:
|
|
|
659
636
|
- `oat config describe ...` to understand sync keys
|
|
660
637
|
- `oat providers set ...` to mutate sync/provider settings
|
|
661
638
|
|
|
662
|
-
Known provider strays
|
|
663
|
-
|
|
664
|
-
|
|
639
|
+
Known provider strays follow sync ownership: repo-wide `knownStrays` entries
|
|
640
|
+
live in `.oat/sync/config.json`, while personal entries live in
|
|
641
|
+
`~/.oat/sync/config.json`. Before resolving user sync settings or writing any
|
|
642
|
+
general user-config change, OAT migrates legacy
|
|
643
|
+
`~/.oat/config.json#knownStrays` by writing the normalized union to the user
|
|
644
|
+
sync config first, then deleting only the legacy key. The migration is
|
|
645
|
+
idempotent.
|
|
665
646
|
|
|
666
647
|
For the provider-sync schema details, use [Sync Config (`.oat/sync/config.json`)](../provider-sync/config.md).
|
|
667
648
|
|
|
@@ -94,6 +94,37 @@ model that ran, and the reviewer must not replace them with self-identification.
|
|
|
94
94
|
The CLI compares the copied values with its gate-owned record before it applies
|
|
95
95
|
the severity threshold.
|
|
96
96
|
|
|
97
|
+
### Review producer identity
|
|
98
|
+
|
|
99
|
+
Dynamic planning workflows can declare their current parent model to a review
|
|
100
|
+
gate without writing a provider or model into shared/user config:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
OAT_GATE_PRODUCER_IDENTITY='<model>:declared' oat gate review ...
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
This is a review-command-only bridge. `oat gate review` accepts it only when
|
|
107
|
+
the value is non-empty and its provenance suffix is exactly `declared`. The
|
|
108
|
+
gate removes the variable from the child reviewer's environment, and non-review
|
|
109
|
+
commands such as `oat gate cross-provider-exec` ignore it.
|
|
110
|
+
|
|
111
|
+
Producer evidence precedence is explicit `--producer-identity`, then a
|
|
112
|
+
qualifying implementation dispatch stamp, then the review-only environment
|
|
113
|
+
declaration, and finally unknown producer behavior. The environment bridge does
|
|
114
|
+
not replace stronger explicit or stamped evidence and does not establish
|
|
115
|
+
observed runtime identity.
|
|
116
|
+
|
|
117
|
+
For final and contiguous-range reviews, each in-scope implementer/fix stamp
|
|
118
|
+
contributes its claimable producer family. If that producer is not claimable or
|
|
119
|
+
has an unknown family, the gate may infer only a family exclusion from the
|
|
120
|
+
stamp's launcher-owned configured target. The target does not become producer
|
|
121
|
+
runtime identity, and generic or unclassifiable targets contribute no family.
|
|
122
|
+
|
|
123
|
+
Keep reusable gate commands producer-neutral in shared and user config.
|
|
124
|
+
Planning skills attach the ephemeral declaration only while executing a
|
|
125
|
+
resolved configured command that invokes `oat gate review`; they leave it
|
|
126
|
+
absent for every other gate command.
|
|
127
|
+
|
|
97
128
|
### Headless completion safety
|
|
98
129
|
|
|
99
130
|
Every `oat gate review` child receives the same headless contract through two
|
|
@@ -492,7 +523,9 @@ By default the dispatcher:
|
|
|
492
523
|
4. Resolves producer identity from `--producer-identity` or dispatch stamps when
|
|
493
524
|
available. Exact phase/task scopes use the matching stamp. `final` and
|
|
494
525
|
contiguous ranges such as `p02-p03` aggregate every in-range implementer/fix
|
|
495
|
-
stamp.
|
|
526
|
+
stamp. A stamp whose producer is not claimable or has an unknown family may
|
|
527
|
+
contribute its classifiable configured target family to aggregate avoidance
|
|
528
|
+
at lower confidence.
|
|
496
529
|
5. Applies `--avoid same-family`.
|
|
497
530
|
6. Checks candidate availability in descending priority order, with target id as
|
|
498
531
|
the tie-breaker.
|
|
@@ -537,7 +570,10 @@ single stamp or when no stamp has a claimable family. Their producer record uses
|
|
|
537
570
|
an unknown representative instead of presenting the latest stamp as aggregate
|
|
538
571
|
truth:
|
|
539
572
|
|
|
540
|
-
- `avoidFamilies` is the stable deduplicated union of claimable known
|
|
573
|
+
- `avoidFamilies` is the stable deduplicated union of claimable known producer
|
|
574
|
+
families plus classifiable configured target families from stamps whose
|
|
575
|
+
producer is not claimable or has an unknown family. A known, claimable
|
|
576
|
+
producer remains authoritative over a conflicting target.
|
|
541
577
|
- `contributingScopes` is the stable document-order list of distinct scopes from
|
|
542
578
|
every relevant stamp.
|
|
543
579
|
- `contributingStampCount` counts every relevant stamp, including unknown or
|
|
@@ -33,6 +33,15 @@ Key behavior:
|
|
|
33
33
|
|
|
34
34
|
- Scope support (`project`, `user`, `all`)
|
|
35
35
|
- Optional interactive stray adoption
|
|
36
|
+
- Cursor-local skills are handled individually: Adopt moves the skill into the
|
|
37
|
+
matching canonical `.agents/skills` directory, while Keep Cursor-only
|
|
38
|
+
preserves it and records its exact path in the applicable sync config
|
|
39
|
+
- Aborting a Cursor migration preserves completed choices and leaves the
|
|
40
|
+
current and remaining skills unresolved
|
|
41
|
+
- Keep Cursor-only is blocked when a canonical skill has the same name; rename
|
|
42
|
+
one skill before retrying
|
|
43
|
+
- Non-interactive and JSON modes report unresolved Cursor skill actions without
|
|
44
|
+
choosing or mutating a disposition
|
|
36
45
|
- JSON output for automation
|
|
37
46
|
|
|
38
47
|
## `oat sync`
|
|
@@ -46,6 +55,20 @@ Key behavior:
|
|
|
46
55
|
- Mutates by default; use `--dry-run` to preview
|
|
47
56
|
- Strategy-aware operations (`symlink`, `copy`, `auto`)
|
|
48
57
|
- Provider enable/disable honored via sync config
|
|
58
|
+
- Cursor skills are native-read from canonical `.agents/skills`; sync does not
|
|
59
|
+
create `.cursor/skills` mirrors
|
|
60
|
+
- Upgrade cleanup removes only verified clean legacy Cursor skill views.
|
|
61
|
+
Changed or unverified views are preserved and detached from obsolete manifest
|
|
62
|
+
ownership.
|
|
63
|
+
|
|
64
|
+
Preview project and user cleanup before applying it:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
oat sync --scope all --dry-run
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Review every planned `remove` and `detach` operation before running the same
|
|
71
|
+
command without `--dry-run`.
|
|
49
72
|
|
|
50
73
|
## `oat providers list`
|
|
51
74
|
|
|
@@ -102,6 +125,9 @@ Key behavior:
|
|
|
102
125
|
## Notes
|
|
103
126
|
|
|
104
127
|
- `oat init --scope project` is commonly used before provider-interop commands because it initializes `.oat/sync/config.json`.
|
|
128
|
+
- User-scope known-stray choices are stored in `~/.oat/sync/config.json`.
|
|
129
|
+
Legacy `~/.oat/config.json#knownStrays` entries migrate automatically before
|
|
130
|
+
user-scope stray filtering.
|
|
105
131
|
- `oat doctor` complements interop workflows by surfacing environment and bundled-skill version issues before or after sync operations.
|
|
106
132
|
|
|
107
133
|
## Adjacent Instruction Integrity Commands
|
|
@@ -5,11 +5,12 @@ description: 'Configuration schema and behavior for provider sync in .oat/sync/c
|
|
|
5
5
|
|
|
6
6
|
# Sync Config (`.oat/sync/config.json`)
|
|
7
7
|
|
|
8
|
-
This document defines the project sync config used by provider-interop commands.
|
|
8
|
+
This document defines the project and user sync config used by provider-interop commands.
|
|
9
9
|
|
|
10
10
|
## Location
|
|
11
11
|
|
|
12
12
|
- Project scope: `.oat/sync/config.json`
|
|
13
|
+
- User scope: `~/.oat/sync/config.json`
|
|
13
14
|
|
|
14
15
|
## Purpose
|
|
15
16
|
|
|
@@ -17,7 +18,7 @@ This document defines the project sync config used by provider-interop commands.
|
|
|
17
18
|
|
|
18
19
|
Discovery note:
|
|
19
20
|
|
|
20
|
-
- `oat config describe` includes
|
|
21
|
+
- `oat config describe` includes both sync config scopes in its catalog so you can inspect sync/provider keys from the main config help surface.
|
|
21
22
|
- Mutation ownership still lives with provider-sync commands such as `oat providers set`, not `oat config set`.
|
|
22
23
|
|
|
23
24
|
It is read by:
|
|
@@ -64,7 +65,7 @@ Entries are exact provider-path matches after path normalization; they are not
|
|
|
64
65
|
globs and do not suppress sibling paths.
|
|
65
66
|
|
|
66
67
|
Project-level config in `.oat/sync/config.json` applies to everyone using the
|
|
67
|
-
repository:
|
|
68
|
+
repository. A Keep Cursor-only choice for a project skill writes here:
|
|
68
69
|
|
|
69
70
|
```json
|
|
70
71
|
{
|
|
@@ -74,11 +75,13 @@ repository:
|
|
|
74
75
|
}
|
|
75
76
|
```
|
|
76
77
|
|
|
77
|
-
User-level config in `~/.oat/config.json`
|
|
78
|
-
files
|
|
78
|
+
User-level config in `~/.oat/sync/config.json` owns personal provider-local
|
|
79
|
+
files and user-scope Keep Cursor-only choices:
|
|
79
80
|
|
|
80
81
|
```json
|
|
81
82
|
{
|
|
83
|
+
"version": 1,
|
|
84
|
+
"defaultStrategy": "auto",
|
|
82
85
|
"knownStrays": [".cursor/skills/cloud-environment-setup"]
|
|
83
86
|
}
|
|
84
87
|
```
|
|
@@ -87,6 +90,12 @@ The common Cursor-only skill case is a good fit: the skill may intentionally
|
|
|
87
90
|
exist in `.cursor/skills/cloud-environment-setup` while remaining outside the
|
|
88
91
|
canonical `.agents/skills` inventory.
|
|
89
92
|
|
|
93
|
+
Earlier releases stored user `knownStrays` in `~/.oat/config.json`. Before OAT
|
|
94
|
+
resolves user sync config or writes any general user-config change, it
|
|
95
|
+
normalizes and unions those entries into `~/.oat/sync/config.json`, writes the
|
|
96
|
+
sync config first, then removes only the legacy key. Repeating the migration is
|
|
97
|
+
safe, including after interruption.
|
|
98
|
+
|
|
90
99
|
## Behavior notes
|
|
91
100
|
|
|
92
101
|
- If `providers.<name>.enabled` is:
|
|
@@ -95,6 +104,8 @@ canonical `.agents/skills` inventory.
|
|
|
95
104
|
- unset: provider falls back to directory detection.
|
|
96
105
|
- `defaultStrategy` is used when no provider-specific `strategy` is set.
|
|
97
106
|
- At runtime, config is normalized so `providers` is always present in memory.
|
|
107
|
+
- Project scans combine project and user known-stray paths. User scans use the
|
|
108
|
+
user sync config.
|
|
98
109
|
- Codex project sync also manages generated materialized roles derived from
|
|
99
110
|
canonical agents and explicit model+effort targets. Dispatch-aware roles such
|
|
100
111
|
as `oat-phase-implementer-gpt-5-6-terra-xhigh` and
|
|
@@ -106,7 +117,7 @@ canonical `.agents/skills` inventory.
|
|
|
106
117
|
- Initial setup (interactive): `oat init --scope project`
|
|
107
118
|
- Explicit updates: `oat providers set --scope project --enabled <providers> --disabled <providers>`
|
|
108
119
|
- Apply sync changes: `oat sync --scope project`
|
|
109
|
-
- Inspect the sync config contract: `oat config describe sync.defaultStrategy` or `oat config describe sync.providers.<name>.enabled`
|
|
120
|
+
- Inspect the sync config contract: `oat config describe sync.defaultStrategy`, `oat config describe sync.knownStrays`, or `oat config describe sync.providers.<name>.enabled`
|
|
110
121
|
|
|
111
122
|
## Related references
|
|
112
123
|
|
|
@@ -5,11 +5,16 @@ description: Standalone adoption lane for canonical assets, provider views, sync
|
|
|
5
5
|
|
|
6
6
|
# Provider Sync
|
|
7
7
|
|
|
8
|
-
Provider Sync is the OAT lane for
|
|
8
|
+
Provider Sync is the OAT lane for reconciling a canonical rules-and-skills
|
|
9
|
+
layout with provider-specific surfaces such as Claude, Cursor, Copilot, Gemini,
|
|
10
|
+
or Codex.
|
|
9
11
|
|
|
10
12
|
You can adopt this layer on its own. It does not require tracked OAT projects, and it is the right starting point when you mainly want interoperability and drift control.
|
|
11
13
|
|
|
12
|
-
In practice, you edit the canonical layout in `.agents/` and `.oat
|
|
14
|
+
In practice, you edit the canonical layout in `.agents/` and `.oat/`. OAT
|
|
15
|
+
generates provider-specific views where required, leaves native-read assets in
|
|
16
|
+
their canonical directories, and keeps intentional provider-local adoption
|
|
17
|
+
surfaces visible.
|
|
13
18
|
|
|
14
19
|
## Contents
|
|
15
20
|
|
|
@@ -22,13 +27,19 @@ In practice, you edit the canonical layout in `.agents/` and `.oat/`, then let O
|
|
|
22
27
|
|
|
23
28
|
## What This Section Is
|
|
24
29
|
|
|
25
|
-
This section explains how OAT treats `.agents/` and `.oat/` as the source of
|
|
30
|
+
This section explains how OAT treats `.agents/` and `.oat/` as the source of
|
|
31
|
+
truth, when provider views are derived from those canonical assets, how
|
|
32
|
+
native-read mappings avoid redundant output, and how provider-local adoption
|
|
33
|
+
surfaces remain discoverable.
|
|
26
34
|
|
|
27
35
|
## What OAT Treats As Canonical
|
|
28
36
|
|
|
29
37
|
- canonical skills, agents, and rules under `.agents/`
|
|
30
38
|
- sync state and related metadata under `.oat/`
|
|
31
|
-
- provider-specific files as derived views
|
|
39
|
+
- provider-specific files as derived views when a mapping requires output
|
|
40
|
+
- native-read assets in canonical directories without mirrored provider files
|
|
41
|
+
- provider-local extension files as adoption candidates until explicitly
|
|
42
|
+
adopted or remembered as intentional strays
|
|
32
43
|
|
|
33
44
|
## Who It's For
|
|
34
45
|
|
|
@@ -41,7 +52,8 @@ This section explains how OAT treats `.agents/` and `.oat/` as the source of tru
|
|
|
41
52
|
1. Run `oat init` to create the base OAT layout and setup state.
|
|
42
53
|
2. Inspect current sync state with `oat status`.
|
|
43
54
|
3. Adjust provider enablement with `oat providers ...` if needed.
|
|
44
|
-
4. Run `oat sync` to materialize provider views
|
|
55
|
+
4. Run `oat sync` to materialize required provider views and reconcile managed
|
|
56
|
+
state. Native-read assets do not produce provider-view operations.
|
|
45
57
|
5. Re-run `oat status` after edits to confirm whether anything drifted or needs adoption.
|
|
46
58
|
|
|
47
59
|
## Start Here
|
|
@@ -55,10 +55,48 @@ Provider files ignored by Git are treated as intentionally local runtime files a
|
|
|
55
55
|
|
|
56
56
|
Provider files listed in sync config `knownStrays` are also omitted from stray
|
|
57
57
|
summaries and adoption prompts. Known strays can be configured at project scope
|
|
58
|
-
in `.oat/sync/config.json` or user scope in `~/.oat/config.json`; entries use
|
|
58
|
+
in `.oat/sync/config.json` or user scope in `~/.oat/sync/config.json`; entries use
|
|
59
59
|
exact provider-path matching, so `.cursor/skills/cloud-environment-setup` does
|
|
60
60
|
not suppress `.cursor/skills/cloud-environment-setup-extra`.
|
|
61
61
|
|
|
62
|
+
### Cursor skill migration
|
|
63
|
+
|
|
64
|
+
Cursor reads canonical project and user skills directly from `.agents/skills`
|
|
65
|
+
and `~/.agents/skills`. OAT therefore treats `.cursor/skills` as a Cursor-only
|
|
66
|
+
extension and adoption surface rather than generated output.
|
|
67
|
+
|
|
68
|
+
Interactive `oat init` and `oat status` ask about every unresolved Cursor-local
|
|
69
|
+
skill separately:
|
|
70
|
+
|
|
71
|
+
- **Adopt:** move the skill to the matching canonical `.agents/skills`
|
|
72
|
+
directory without creating a Cursor skill view or manifest row. If identical
|
|
73
|
+
canonical content already exists, OAT removes the redundant Cursor-local
|
|
74
|
+
copy.
|
|
75
|
+
- **Keep Cursor-only:** leave the skill in place and immediately add its exact
|
|
76
|
+
normalized path to the applicable project or user sync config.
|
|
77
|
+
- **Abort:** keep the current and remaining skills unresolved. Choices already
|
|
78
|
+
completed in the same run remain saved.
|
|
79
|
+
|
|
80
|
+
Keep Cursor-only is unavailable when a canonical skill has the same name.
|
|
81
|
+
Rename one skill before retrying; Cursor does not document a safe precedence
|
|
82
|
+
rule for duplicates discovered from both roots. Non-interactive and JSON modes
|
|
83
|
+
report pending migration actions without choosing or mutating a disposition.
|
|
84
|
+
|
|
85
|
+
### Retiring legacy Cursor skill views
|
|
86
|
+
|
|
87
|
+
When upgrading from generated Cursor skill views, sync classifies each obsolete
|
|
88
|
+
manifest-owned path before acting:
|
|
89
|
+
|
|
90
|
+
- Verified clean symlinks and managed copies are removed with their manifest
|
|
91
|
+
entries.
|
|
92
|
+
- Missing paths lose only their stale manifest entries.
|
|
93
|
+
- Modified, replaced, broken, unreadable, or otherwise unverified paths are
|
|
94
|
+
preserved while OAT detaches their obsolete manifest ownership.
|
|
95
|
+
- Unmanaged Cursor-only content is never removed.
|
|
96
|
+
|
|
97
|
+
Use `oat sync --scope <project|user|all> --dry-run` to distinguish planned
|
|
98
|
+
removal from preserve-and-detach operations before running a mutating sync.
|
|
99
|
+
|
|
62
100
|
For rules, adoption maps provider-native files back into `.agents/rules/*.md`:
|
|
63
101
|
|
|
64
102
|
- Claude: `.claude/rules/*.md`
|
|
@@ -16,16 +16,17 @@ description: 'Provider-specific path mappings for Claude, Cursor, Copilot, Gemin
|
|
|
16
16
|
|
|
17
17
|
=== "Cursor"
|
|
18
18
|
|
|
19
|
-
- Project
|
|
20
|
-
- User
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
19
|
+
- Project skills are native-read from `.agents/skills`; agents and rules still sync to `.cursor/agents` and `.cursor/rules`
|
|
20
|
+
- User skills are native-read from `~/.agents/skills`; agents still sync to `~/.cursor/agents`
|
|
21
|
+
- `.cursor/skills` and `~/.cursor/skills` remain supported Cursor-only extension and adoption surfaces. OAT does not generate skill views there.
|
|
22
|
+
- Interactive `oat init` and `oat status` ask for an individual disposition for each unresolved Cursor-local skill: adopt it into `.agents/skills` or keep it Cursor-only and remember the exact path in sync config
|
|
23
|
+
- Keep-local is blocked when a canonical skill has the same name because Cursor does not document a safe duplicate-resolution order
|
|
24
|
+
- During upgrades, OAT removes only verified clean legacy managed skill views. Changed or replaced views are preserved, detached from manifest ownership, and offered for migration.
|
|
25
|
+
- Sync materializes pinned Markdown definitions for both `oat-phase-implementer` and `oat-reviewer`. Each generated name keeps the configured flat ladder ID, while an explicit verified mapping writes the separate bracket-form frontmatter model. OAT never derives one form from the other.
|
|
26
|
+
- Generated definitions carry `supported-catalogue`, `project-config`, or `user-config` ownership. Project and supported output lives in the tracked `.cursor/agents` view; user-owned output lives under `~/.cursor/agents`. Cleanup reconciles only the applicable owner.
|
|
27
|
+
- Managed dispatch requires `providers.cursor.dispatchArgs.variant` and launches that exact resolver-selected native agent type first. Skills do not pass a Task-level model argument or normalize Cursor model strings.
|
|
28
|
+
- Cursor may silently fallback when a definition pin cannot be honored. Variant acceptance therefore establishes launcher-owned `configured` provenance only; runtime identity remains `not-reported` unless independently observed.
|
|
29
|
+
- `oat doctor` checks whether each flat ID is still present in the current Cursor catalogue and reports availability drift. Catalogue availability is diagnostic and does not prove that a definition-level bracket pin ran as configured.
|
|
29
30
|
- Rule files render as `.cursor/rules/*.mdc`
|
|
30
31
|
|
|
31
32
|
=== "Copilot"
|
|
@@ -81,9 +82,9 @@ oat config adopt dispatch-matrix --user
|
|
|
81
82
|
```
|
|
82
83
|
|
|
83
84
|
Project-config candidates materialize into the tracked, version-controlled
|
|
84
|
-
project `.codex`
|
|
85
|
-
OAT does not auto-ignore project output or create
|
|
86
|
-
that repository change.
|
|
85
|
+
project `.codex` and `.cursor` views. User-config candidates materialize under
|
|
86
|
+
`~/.codex` and `~/.cursor`. OAT does not auto-ignore project output or create
|
|
87
|
+
its Git commit; the team owns that repository change.
|
|
87
88
|
|
|
88
89
|
At implementation time, the root passes the recorded named maximum through
|
|
89
90
|
invocation-only `--ceiling-tier`, resolves one exact candidate per phase, and
|
|
@@ -91,24 +92,27 @@ dispatches one phase implementer. Codex first attempts the resolver-returned
|
|
|
91
92
|
materialized role as the native `agent_type`. The launcher records the target,
|
|
92
93
|
model axis, and effort axis from that resolved payload; child self-report is not
|
|
93
94
|
provenance and cannot replace those values.
|
|
94
|
-
Only an explicit pre-start native role-selection rejection permits
|
|
95
|
-
|
|
95
|
+
Only an explicit pre-start native role-selection rejection permits another
|
|
96
|
+
target-preserving route. An accepted child, including one that later returns
|
|
96
97
|
`BLOCKED` or lacks telemetry, is a task outcome rather than a fallback signal.
|
|
97
|
-
Claude
|
|
98
|
-
|
|
99
|
-
or a base role.
|
|
98
|
+
Claude binds the exact model argument described above. Cursor launches the
|
|
99
|
+
exact native variant. A missing or unselectable managed target blocks rather
|
|
100
|
+
than falling back to the root target or a base role.
|
|
100
101
|
|
|
101
102
|
## Scope rules
|
|
102
103
|
|
|
103
104
|
- Project scope: skills + agents + rules
|
|
104
|
-
- User scope: skills, plus the two bundled managed Codex role definitions used only for user-owned target expansion (provider mappings vary by adapter)
|
|
105
|
+
- User scope: skills, plus the two bundled managed Codex and Cursor role definitions used only for user-owned target expansion (provider mappings vary by adapter)
|
|
105
106
|
- Rules are project-scoped only in this release
|
|
106
107
|
- Codex user-scope sync materializes user-config custom roles under `~/.codex`; project-config and supported-catalogue output remains project-scoped and version controlled
|
|
108
|
+
- Cursor user-scope sync materializes user-config variants under `~/.cursor/agents`; project-config and supported-catalogue output remains project-scoped and version controlled
|
|
107
109
|
|
|
108
110
|
## Adoption model
|
|
109
111
|
|
|
110
112
|
- Stray adoption is available in `oat init` and `oat status`.
|
|
111
113
|
- Adoption reconciles canonical plus the adopted provider first.
|
|
114
|
+
- Native-read Cursor skill adoption moves the provider-local skill into `.agents/skills` without recreating a `.cursor/skills` view or manifest entry.
|
|
115
|
+
- Choosing Keep Cursor-only leaves the skill in place and records its exact normalized path in the project or user sync config.
|
|
112
116
|
- Rule adoption normalizes provider filenames back to canonical `.agents/rules/*.md` entries before cross-provider fanout.
|
|
113
117
|
- Cross-provider fanout is explicit via `oat sync --scope all`.
|
|
114
118
|
|