@open-agent-toolkit/cli 0.2.30 → 0.2.32

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.
Files changed (107) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/cli-utilities/configuration.md +41 -0
  3. package/assets/docs/contributing/code.md +19 -7
  4. package/assets/docs/contributing/explainer-kit-verification.md +9 -1
  5. package/assets/docs/contributing/skills.md +9 -0
  6. package/assets/docs/provider-sync/commands.md +15 -10
  7. package/assets/docs/provider-sync/manifest-and-drift.md +23 -0
  8. package/assets/docs/provider-sync/providers.md +8 -2
  9. package/assets/docs/provider-sync/scope-and-surface.md +3 -1
  10. package/assets/docs/reference/file-locations.md +5 -0
  11. package/assets/docs/reference/troubleshooting.md +18 -0
  12. package/assets/docs/workflows/skills/explainer-kit-providers.md +16 -5
  13. package/assets/docs/workflows/skills/explainer-kit.md +98 -38
  14. package/assets/public-package-versions.json +4 -4
  15. package/assets/skills/create-agnostic-skill/references/docs/skills-guide.md +34 -22
  16. package/assets/skills/explainer-kit/SKILL.md +33 -8
  17. package/assets/skills/explainer-kit/briefs/project-recap.md +25 -7
  18. package/assets/skills/explainer-kit/recipes/project-recap.v2.json +72 -0
  19. package/assets/skills/explainer-kit/references/contracts.md +49 -17
  20. package/assets/skills/explainer-kit/references/destination-contract.md +141 -25
  21. package/assets/skills/explainer-kit/references/extension-contract.md +19 -10
  22. package/assets/skills/explainer-kit/references/visual-authoring.md +24 -0
  23. package/assets/skills/explainer-kit/references/visual-review.md +19 -5
  24. package/assets/skills/explainer-kit/schemas/author-request.v3.schema.json +241 -0
  25. package/assets/skills/explainer-kit/schemas/publish-receipt.v2.schema.json +215 -0
  26. package/assets/skills/explainer-kit/schemas/publish-request.v2.schema.json +34 -0
  27. package/assets/skills/explainer-kit/schemas/run-request.schema.json +4 -1
  28. package/assets/skills/explainer-kit/schemas/terminal-evidence.v1.schema.json +81 -0
  29. package/assets/skills/explainer-kit/schemas/visual-review-evidence.v1.schema.json +66 -0
  30. package/assets/skills/explainer-kit/scripts/lib/catalog.mjs +109 -3
  31. package/assets/skills/explainer-kit/scripts/lib/contracts.mjs +550 -17
  32. package/assets/skills/explainer-kit/scripts/lib/durability.mjs +90 -8
  33. package/assets/skills/explainer-kit/scripts/lib/fs-safe.mjs +5 -0
  34. package/assets/skills/explainer-kit/scripts/lib/internal-references.mjs +538 -0
  35. package/assets/skills/explainer-kit/scripts/lib/package-coverage.mjs +129 -11
  36. package/assets/skills/explainer-kit/scripts/lib/publication-policy.mjs +54 -0
  37. package/assets/skills/explainer-kit/scripts/lib/recipes.mjs +2 -1
  38. package/assets/skills/explainer-kit/scripts/lib/records.mjs +139 -22
  39. package/assets/skills/explainer-kit/scripts/lib/s3-roots.mjs +353 -0
  40. package/assets/skills/explainer-kit/scripts/lib/s3-static.mjs +237 -107
  41. package/assets/skills/explainer-kit/scripts/lib/set-plan.mjs +1 -0
  42. package/assets/skills/explainer-kit/scripts/lib/terminal-evidence.mjs +157 -0
  43. package/assets/skills/explainer-kit/scripts/lib/visual-review.mjs +26 -6
  44. package/assets/skills/explainer-kit/scripts/run.mjs +1006 -144
  45. package/assets/skills/oat-agent-instructions-analyze/references/docs/provider-reference.md +14 -2
  46. package/assets/skills/oat-agent-instructions-apply/references/docs/provider-reference.md +14 -2
  47. package/assets/skills/oat-explainer-kit/SKILL.md +16 -3
  48. package/assets/skills/oat-explainer-kit/references/config-contract.md +13 -8
  49. package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +50 -6
  50. package/assets/skills/oat-explainer-kit/references/migration.md +2 -1
  51. package/assets/skills/oat-explainer-kit/references/visual-review-callback.md +11 -0
  52. package/assets/skills/oat-explainer-kit/scripts/bind-project-sources.mjs +37 -15
  53. package/assets/skills/oat-explainer-kit/scripts/check-terminal-outcome.mjs +83 -0
  54. package/assets/skills/oat-explainer-kit/scripts/derive-destination.mjs +91 -0
  55. package/assets/skills/oat-explainer-kit/scripts/finalize-tracked-run.mjs +66 -10
  56. package/assets/skills/oat-explainer-kit/scripts/resolve-config.mjs +60 -21
  57. package/assets/skills/oat-explainer-kit/scripts/resolve-paths.mjs +52 -8
  58. package/assets/skills/oat-explainer-kit/scripts/run.mjs +271 -36
  59. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +2 -2
  60. package/assets/skills/oat-project-complete/SKILL.md +19 -3
  61. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +2 -2
  62. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +8 -0
  63. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +2 -2
  64. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +2 -2
  65. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +2 -2
  66. package/dist/commands/config/index.d.ts.map +1 -1
  67. package/dist/commands/config/index.js +18 -0
  68. package/dist/commands/init/index.d.ts +2 -2
  69. package/dist/commands/init/index.d.ts.map +1 -1
  70. package/dist/commands/init/index.js +22 -13
  71. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  72. package/dist/commands/project/archive/archive-utils.js +57 -7
  73. package/dist/commands/project/archive/explainer-terminal-evidence.d.ts +29 -0
  74. package/dist/commands/project/archive/explainer-terminal-evidence.d.ts.map +1 -0
  75. package/dist/commands/project/archive/explainer-terminal-evidence.js +37 -0
  76. package/dist/commands/remove/skill/remove-skill.d.ts +4 -1
  77. package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
  78. package/dist/commands/remove/skill/remove-skill.js +44 -5
  79. package/dist/commands/shared/adopt-stray.d.ts +5 -0
  80. package/dist/commands/shared/adopt-stray.d.ts.map +1 -1
  81. package/dist/commands/shared/adopt-stray.js +25 -4
  82. package/dist/commands/shared/native-skill-disposition.d.ts +22 -0
  83. package/dist/commands/shared/native-skill-disposition.d.ts.map +1 -0
  84. package/dist/commands/shared/native-skill-disposition.js +60 -0
  85. package/dist/commands/status/index.d.ts +2 -2
  86. package/dist/commands/status/index.d.ts.map +1 -1
  87. package/dist/commands/status/index.js +22 -13
  88. package/dist/config/oat-config.d.ts +2 -0
  89. package/dist/config/oat-config.d.ts.map +1 -1
  90. package/dist/config/oat-config.js +4 -0
  91. package/dist/config/resolve.d.ts.map +1 -1
  92. package/dist/config/resolve.js +1 -0
  93. package/dist/engine/compute-plan.d.ts +3 -2
  94. package/dist/engine/compute-plan.d.ts.map +1 -1
  95. package/dist/engine/compute-plan.js +1 -1
  96. package/dist/engine/index.d.ts +1 -1
  97. package/dist/engine/index.d.ts.map +1 -1
  98. package/dist/engine/index.js +1 -1
  99. package/dist/providers/copilot/paths.d.ts.map +1 -1
  100. package/dist/providers/copilot/paths.js +6 -4
  101. package/package.json +2 -2
  102. package/dist/commands/shared/cursor-skill-disposition.d.ts +0 -17
  103. package/dist/commands/shared/cursor-skill-disposition.d.ts.map +0 -1
  104. package/dist/commands/shared/cursor-skill-disposition.js +0 -41
  105. /package/assets/skills/explainer-kit/recipes/{project-recap.json → project-recap.v1.json} +0 -0
  106. /package/assets/skills/explainer-kit/schemas/{publish-receipt.schema.json → publish-receipt.v1.schema.json} +0 -0
  107. /package/assets/skills/explainer-kit/schemas/{publish-request.schema.json → publish-request.v1.schema.json} +0 -0
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "oatVersion": "0.2.30"
3
+ "oatVersion": "0.2.32"
4
4
  }
@@ -138,6 +138,7 @@ plumbing uses `explainers.*`; project lifecycle preferences use
138
138
  | `explainers.publish.publicBaseUrl` | HTTPS URL | shared | unset |
139
139
  | `explainers.publish.awsRegion` | non-empty string | shared | unset |
140
140
  | `explainers.publish.awsProfile` | non-empty string | local, user | unset |
141
+ | `explainers.publish.publicAccess` | `public\|protected` | shared | `public` |
141
142
  | `workflow.explainers.projectExplainer` | `always\|ask\|never` | local, shared, user | `ask` |
142
143
  | `workflow.explainers.projectRecap` | `always\|ask\|never` | local, shared, user | `ask` |
143
144
 
@@ -172,6 +173,46 @@ chain applies. Config never starts publishing by itself: lifecycle callers must
172
173
  still select publish durability explicitly, and publishing remains
173
174
  human-gated. Raw AWS credentials are not config keys.
174
175
 
176
+ `publicAccess` declares whether published objects are expected to be reachable
177
+ anonymously; it does not authorize publication and it does not change any
178
+ bucket policy. It selects how publication is verified. The default `public`
179
+ fetches every uploaded object over HTTPS and compares the returned bytes
180
+ against the manifest hash. `protected` skips those anonymous fetches, verifies
181
+ each object through authenticated S3 hashing instead, and records
182
+ `skipped-protected` in the publish receipt. Because no anonymous fetch happens
183
+ under `protected`, a mistyped `publicBaseUrl` is not detected at publish time:
184
+ the advertised URLs are still written into the initiative catalog and receipt,
185
+ and the catalog records `publicVerification: "skipped-by-policy"` so consumers
186
+ can see the URLs were never exercised.
187
+
188
+ ### Explainer publication environment variables
189
+
190
+ Two escape hatches are read from the process environment rather than from
191
+ config, because both are machine-local operational overrides rather than
192
+ project settings. Neither has a config key.
193
+
194
+ | Variable | Effect | Default |
195
+ | ------------------------------------------------ | --------------------------------------------------------------------------- | ------- |
196
+ | `EXPLAINER_KIT_ALLOW_PRIVATE_PUBLIC_ROOT` | Permits a loopback, link-local, unique-local or RFC 1918 `publicBaseUrl` | off |
197
+ | `EXPLAINER_KIT_SUPPRESS_ROOT_DIVERGENCE_WARNING` | Silences the advisory warning when the S3 key prefix and public path differ | off |
198
+
199
+ Both accept `1`, `true` or `on`.
200
+
201
+ `EXPLAINER_KIT_ALLOW_PRIVATE_PUBLIC_ROOT` disables an anti-SSRF control. Public
202
+ verification issues an outbound GET against whatever `publicBaseUrl` names, so
203
+ by default the connector refuses internal addresses — including the
204
+ `169.254.169.254` instance-metadata endpoint. Enable it only for a genuinely
205
+ internal mirror. When it is set and the root is in fact non-public, the run
206
+ records `publicRootPolicy: "private-allowed"` in the publish receipt, so a
207
+ publication made with the control disabled is distinguishable in durable
208
+ evidence from one made without it. The policy is address-literal only: a
209
+ hostname that resolves inward is not detected either way.
210
+
211
+ `EXPLAINER_KIT_SUPPRESS_ROOT_DIVERGENCE_WARNING` only affects an advisory
212
+ message. Divergent roots are never a publication failure — a CloudFront Origin
213
+ Path deployment legitimately maps a bucket prefix to the distribution root — so
214
+ this changes no validation outcome.
215
+
175
216
  See [Explainer Kit](../workflows/skills/explainer-kit.md) for recipes, artifact
176
217
  locations, lifecycle behavior, and durability.
177
218
 
@@ -41,18 +41,30 @@ OAT is organized as a pnpm workspace with Turborepo orchestration.
41
41
 
42
42
  ## Quality Gates
43
43
 
44
- Run the workspace checks that match your change surface:
44
+ Every change runs the ordered Definition of Done from the root `AGENTS.md`,
45
+ which mirrors CI's gate steps exactly so a locally green run implies CI green:
45
46
 
46
47
  ```bash
47
- pnpm test
48
- pnpm lint
49
- pnpm format
48
+ pnpm check
50
49
  pnpm type-check
51
- pnpm build # excludes docs for speed
52
- pnpm build:docs # builds docs site and its dependencies
50
+ pnpm test
51
+ pnpm build # excludes docs for speed
52
+ pnpm run check:skill-bumps # changed .agents/skills/*/SKILL.md must bump version
53
+ pnpm release:check-versions # lockstep public package version bumps
54
+ pnpm release:validate
55
+ pnpm build:docs # builds docs site and its dependencies
53
56
  ```
54
57
 
55
- For narrower changes, use package-specific checks when possible, but do not merge without passing the relevant workspace gates.
58
+ `pnpm test` is composite: it runs the workspace vitest suites, then
59
+ `test:smoke` (`tools/smoke`), `test:skills` (`.agents/skills/*/tests`), and
60
+ the named-file `test:release` set. Steps 5 and 6 are the version-lockstep
61
+ gates; they are in the local list because they previously ran only in CI and
62
+ version-bump drift twice reached review with no local gate to surface it.
63
+
64
+ CI runs neither `pnpm lint` nor `pnpm format` — run both whenever a change
65
+ touches `tools/smoke` or `.agents/skills`, since nothing else covers them.
66
+ For narrower changes, use package-specific checks when possible, but do not
67
+ merge without passing the relevant workspace gates.
56
68
 
57
69
  ### TypeScript and type-aware linting
58
70
 
@@ -62,6 +62,11 @@ The suite recomputes semantic-input hashes, grounds every claim in retained
62
62
  source evidence, and evaluates the shared rubric against live runtime output.
63
63
  A prose claim or status label without runtime proof does not pass.
64
64
 
65
+ The existing three-case, 27-capture golden suite is intentionally unchanged by
66
+ the prose-led visual-review work. Simplifying it is a separate follow-up: first
67
+ audit each case's unique coverage, runtime cost, and flakiness, then remove or
68
+ replace fixtures only with evidence that the same behavior remains protected.
69
+
65
70
  ## Inspect generated evidence
66
71
 
67
72
  The suite materializes each case's runtime package under its temporary working
@@ -114,9 +119,12 @@ pnpm check
114
119
  pnpm type-check
115
120
  pnpm test
116
121
  pnpm build
122
+ pnpm run check:skill-bumps
123
+ pnpm release:check-versions
124
+ pnpm release:validate
125
+ pnpm build:docs
117
126
  pnpm lint
118
127
  pnpm format
119
- pnpm build:docs
120
128
  git diff --check
121
129
  ```
122
130
 
@@ -43,6 +43,15 @@ Skill behavior is defined by frontmatter plus the process contract in each `SKIL
43
43
  - `allowed-tools`
44
44
  - `oat_gateable`
45
45
 
46
+ ### The `version` field is gated
47
+
48
+ Changing any canonical skill's `SKILL.md` requires bumping its frontmatter
49
+ `version` in the same PR — one bump per changed skill in the final PR diff,
50
+ even if the skill was edited multiple times on the branch. The rule is
51
+ enforced by `pnpm run check:skill-bumps`, which runs locally (root `AGENTS.md`
52
+ Definition of Done) and in CI; a changed skill whose version matches
53
+ `origin/main` fails the gate.
54
+
46
55
  ## Practical Authoring Flow
47
56
 
48
57
  1. Decide whether you are adding a general reusable skill or an OAT-specific lifecycle skill.
@@ -33,15 +33,16 @@ 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
+ - Cursor-local and Copilot-local skills are handled individually: Adopt moves
37
+ the skill into the matching canonical `.agents/skills` directory, while Keep
38
+ provider-only preserves it and records its exact path in the applicable sync
39
+ config
40
+ - Aborting a native-read skill migration preserves completed choices and leaves
41
+ the current and remaining skills unresolved
42
+ - Keep provider-only is blocked when a canonical skill has the same name;
43
+ rename one skill before retrying
44
+ - Non-interactive and JSON modes report unresolved native-read skill actions
45
+ without choosing or mutating a disposition
45
46
  - JSON output for automation
46
47
 
47
48
  ## `oat sync`
@@ -57,7 +58,11 @@ Key behavior:
57
58
  - Provider enable/disable honored via sync config
58
59
  - Cursor skills are native-read from canonical `.agents/skills`; sync does not
59
60
  create `.cursor/skills` mirrors
60
- - Upgrade cleanup removes only verified clean legacy Cursor skill views.
61
+ - Copilot skills are native-read from canonical `.agents/skills`; sync does not
62
+ create `.github/skills` or `~/.copilot/skills` mirrors. Copilot agents and
63
+ project rules still sync to `.github/agents`, `~/.copilot/agents`, and
64
+ `.github/instructions`.
65
+ - Upgrade cleanup removes only verified clean legacy Cursor or Copilot skill views.
61
66
  Changed or unverified views are preserved and detached from obsolete manifest
62
67
  ownership.
63
68
 
@@ -97,6 +97,29 @@ manifest-owned path before acting:
97
97
  Use `oat sync --scope <project|user|all> --dry-run` to distinguish planned
98
98
  removal from preserve-and-detach operations before running a mutating sync.
99
99
 
100
+ ### Copilot skill migration
101
+
102
+ Copilot reads canonical project and user skills directly from `.agents/skills`
103
+ and `~/.agents/skills`. OAT no longer generates `.github/skills` or
104
+ `~/.copilot/skills` views, but it still scans those legacy directories as
105
+ adoption sources.
106
+
107
+ Interactive `oat init` and `oat status` ask about each unresolved Copilot-local
108
+ skill separately. Adopt moves it into the matching canonical directory without
109
+ recreating a provider view or manifest entry. Keep Copilot-only leaves it in
110
+ place and records its exact path as a known stray. A same-name canonical skill
111
+ blocks Keep Copilot-only until one package is renamed. Non-interactive and JSON
112
+ modes report pending migration actions without choosing a disposition.
113
+
114
+ During upgrade cleanup, OAT removes only verified clean manifest-owned views.
115
+ Changed, replaced, broken, unreadable, or otherwise unverifiable paths are
116
+ preserved and detached from obsolete manifest ownership so they remain
117
+ available for adoption or manual resolution.
118
+
119
+ Copilot agent mappings remain materialized under `.github/agents` and
120
+ `~/.copilot/agents`, and project rules remain rendered under
121
+ `.github/instructions`; this retirement behavior applies only to skill views.
122
+
100
123
  For rules, adoption maps provider-native files back into `.agents/rules/*.md`:
101
124
 
102
125
  - Claude: `.claude/rules/*.md`
@@ -31,8 +31,12 @@ description: 'Provider-specific path mappings for Claude, Cursor, Copilot, Gemin
31
31
 
32
32
  === "Copilot"
33
33
 
34
- - Project: `.agents/skills` -> `.github/skills`, `.agents/agents` -> `.github/agents`, `.agents/rules` -> `.github/instructions`
35
- - User: `~/.agents/skills` -> `~/.copilot/skills`, `~/.agents/agents` -> `~/.copilot/agents`
34
+ - Project skills are native-read from `.agents/skills`; agents and rules still sync to `.github/agents` and `.github/instructions`
35
+ - User skills are native-read from `~/.agents/skills`; agents still sync to `~/.copilot/agents`
36
+ - `.github/skills` and `~/.copilot/skills` are legacy adoption sources. OAT does not generate skill views there.
37
+ - Interactive `oat init` and `oat status` ask for an individual disposition for each unresolved Copilot-local skill: adopt it into `.agents/skills` or keep it Copilot-only and remember the exact path in sync config
38
+ - Keep-local is blocked when a canonical skill has the same name
39
+ - During upgrades, OAT removes only verified clean legacy managed skill views. Changed or unverifiable views are preserved, detached from manifest ownership, and offered for adoption.
36
40
  - Rule files render as `.github/instructions/*.instructions.md`
37
41
  - Canonical always-on rules render with `applyTo: "**"` so Copilot activates them repo-wide; provider rules with exactly `applyTo: "**"` adopt back to `activation: always`
38
42
  - Comma-containing globs are not supported for Copilot rule sync because Copilot uses a comma-separated `applyTo` field
@@ -113,6 +117,8 @@ than falling back to the root target or a base role.
113
117
  - Adoption reconciles canonical plus the adopted provider first.
114
118
  - Native-read Cursor skill adoption moves the provider-local skill into `.agents/skills` without recreating a `.cursor/skills` view or manifest entry.
115
119
  - Choosing Keep Cursor-only leaves the skill in place and records its exact normalized path in the project or user sync config.
120
+ - 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.
121
+ - Choosing Keep Copilot-only leaves the skill in place and records its exact normalized path in the project or user sync config.
116
122
  - Rule adoption normalizes provider filenames back to canonical `.agents/rules/*.md` entries before cross-provider fanout.
117
123
  - Cross-provider fanout is explicit via `oat sync --scope all`.
118
124
 
@@ -13,8 +13,9 @@ This capability is intentionally independent from OAT workflow artifacts. Teams
13
13
 
14
14
  - Canonical directories: `.agents/skills`, `.agents/agents`, `.agents/rules`
15
15
  - Managed provider views: `.claude/*`, `.cursor/*`, `.github/*`, `.copilot/*`, `.codex/*` (where applicable)
16
- - Native-read mappings use canonical `.agents/*` directly without mirrored provider directories. Cursor skills, Gemini skills and agents, and Codex canonical mappings use this model.
16
+ - 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.
17
17
  - Cursor's `.cursor/skills` and `~/.cursor/skills` directories are provider-local extension and adoption surfaces, not managed output directories.
18
+ - Copilot's legacy `.github/skills` and `~/.copilot/skills` directories are adoption sources, not managed output directories. Copilot agents and project rules still use `.github/agents`, `~/.copilot/agents`, and `.github/instructions` provider views.
18
19
  - Manifest tracking: `.oat/sync/manifest.json` (project) and `~/.oat/sync/manifest.json` (user)
19
20
 
20
21
  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.
@@ -51,6 +52,7 @@ Rules are currently project-scoped canonical content. Unlike skills and agents,
51
52
  - `oat init --scope project` (interactive) prompts for supported providers and persists explicit true/false values.
52
53
  - `oat sync --scope project` uses config-aware provider activation and can prompt to remediate detected mismatches.
53
54
  - Cursor provider enablement still controls agents, rules, migration discovery, and legacy cleanup even though Cursor reads canonical skills without a generated skill view.
55
+ - Copilot provider enablement still controls agents, project rules, migration discovery, and legacy cleanup even though Copilot reads canonical skills without a generated skill view.
54
56
  - Codex project-scope subagent sync writes `.codex/config.toml` and `.codex/agents/*.toml` at 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.
55
57
  - Default Codex execution requires `root (0) → phase implementer (1)`. Sync and direct materialization continue to apply an `agents.max_depth` floor of `2` as 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.toml` and does not read or change project configuration.
56
58
  - Missing depth or depth `1` does not block default phase execution. Invalid values or explicit values below `1` fail managed implementation preflight. `oat doctor` reports whether optional depth-two nesting is available and gives a scope-specific repair when the configured value is unusable.
@@ -17,6 +17,11 @@ For detailed `.oat/` tree semantics, see:
17
17
  - Cursor reads project skills directly from `.agents/skills/` and user skills
18
18
  directly from `~/.agents/skills/`. `.cursor/skills/` remains a Cursor-only
19
19
  extension and adoption surface, not generated output.
20
+ - Copilot reads project skills directly from `.agents/skills/` and user skills
21
+ directly from `~/.agents/skills/`. OAT treats legacy `.github/skills/` and
22
+ `~/.copilot/skills/` as adoption sources, not generated output. Copilot agents
23
+ still sync to `.github/agents/` and `~/.copilot/agents/`, and project rules
24
+ still sync to `.github/instructions/`.
20
25
 
21
26
  ## OAT runtime/state
22
27
 
@@ -31,6 +31,24 @@ Use `.cursor/skills` only for intentionally Cursor-specific packages. Interactiv
31
31
  `oat init` and `oat status` offer each unresolved Cursor-local skill for
32
32
  canonical adoption or a remembered Keep Cursor-only choice.
33
33
 
34
+ ## Copilot appears detected but no skill sync actions are listed
35
+
36
+ Expected for native-read skill mappings. Verify project skills under
37
+ `.agents/skills` and personal skills under `~/.agents/skills`; Copilot reads
38
+ those canonical directories directly. Sync will not create `.github/skills` or
39
+ `~/.copilot/skills` mirrors.
40
+
41
+ Legacy skills in those provider directories remain adoption candidates. Run
42
+ `oat sync --scope <project|user|all> --dry-run` before upgrading: verified clean
43
+ managed views may be removed, while changed or unverifiable paths are preserved
44
+ and detached from obsolete manifest ownership. Copilot agents and project rules
45
+ continue to sync to `.github/agents`, `~/.copilot/agents`, and
46
+ `.github/instructions`.
47
+
48
+ Interactive `oat init` and `oat status` offer each unresolved legacy skill for
49
+ canonical adoption or a remembered Keep Copilot-only choice. Keep is blocked
50
+ when a same-name canonical skill exists; rename one package before retrying.
51
+
34
52
  ## `sync` reports provider config mismatch
35
53
 
36
54
  - For interactive runs, select detected providers to enable when prompted.
@@ -38,9 +38,11 @@ The provider-neutral `planSet` callback runs once after fact reconciliation and
38
38
  before any author callback. It returns the complete portfolio and one shared
39
39
  claim ledger.
40
40
 
41
- For a project recap, the portfolio must contain the required hub, architecture
42
- view, and deck. Optional entries must use a recipe-licensed profile, remain
43
- inside recipe and per-profile limits, and carry source-backed justification.
41
+ For a new project recap, the portfolio must contain the required navigational
42
+ hub. A diagram, deck, or deep dive is optional and must use a recipe-licensed
43
+ profile, remain inside recipe and per-profile limits, and answer a distinct
44
+ reader question with source evidence and a medium rationale. Version 1 recap
45
+ plans remain readable for replay with their historical three-artifact floor.
44
46
  Duplicate identities, undeclared sources, conflicting shared terms, and
45
47
  unjustified optionals fail validation.
46
48
 
@@ -50,14 +52,16 @@ artifact. Authors cannot add, remove, replace, or rename portfolio entries.
50
52
  ## Artifact author
51
53
 
52
54
  The core invokes `author` once per planned artifact with
53
- `explainer-kit.author-request/v2`. The request contains:
55
+ `explainer-kit.author-request/v3`. Version 2 requests remain readable for
56
+ replay. The current request contains:
54
57
 
55
58
  - artifact identity, type, and authoring path;
56
59
  - the versioned brief and bundled medium-specific guidance;
57
60
  - reconciled facts and the shared set context;
58
61
  - the matching planned artifact;
59
62
  - the resolved theme; and
60
- - the bundled shell for artistic HTML.
63
+ - the bundled shell for artistic HTML; and
64
+ - canonical artifact links ending in explicit `index.html` paths.
61
65
 
62
66
  Return `explainer-kit.author-result/v2` with exactly one of
63
67
  `content.markdown` or `content.html` and non-secret provenance. The core
@@ -128,6 +132,13 @@ all reviewed artifact IDs, structured findings, and one disposition:
128
132
  - `correct` requests one bounded correction and one final review; or
129
133
  - `fail` terminates the gate.
130
134
 
135
+ Judge typography, hierarchy, composition, density, medium leverage, template
136
+ repetition, diagram semantics, and cross-artifact cohesion from the bound
137
+ browser evidence. `pass` means no required correction remains. `correct`
138
+ findings name concrete artifact-scoped actions that can be completed in the
139
+ single bounded correction round. Keep this judgment in prose; do not invent
140
+ numeric scores or geometry thresholds.
141
+
131
142
  The critic must not mutate rendered files or evidence. The core revalidates all
132
143
  bound bytes after each callback.
133
144
 
@@ -20,19 +20,19 @@ OAT lifecycle callers use the adapter.
20
20
 
21
21
  ## Recipes
22
22
 
23
- The core ships four versioned recipes on the `explainer-kit.recipe/v2` file
24
- schema. Each recipe's own `version` selector remains `"1"`, so `{id, version}`
25
- callers and manifest cross-checks are unaffected by the schema move.
23
+ The core ships four recipe families on the `explainer-kit.recipe/v2` file
24
+ schema. Most recipe selectors remain at version `"1"`. New project recaps use
25
+ immutable `project-recap@2`, while `project-recap@1` remains readable for replay.
26
26
 
27
27
  A v2 recipe declares a **floor** — the artifacts every run must produce — plus
28
28
  a licensed **expansion** set. Most recipes retain one floor artifact.
29
- Unattended `project-recap` is the exception: it plans and composes an adaptive
30
- minimum set before any artifact author runs.
29
+ `project-recap@2` requires one complete navigational hub and plans any additional
30
+ artifact before an author runs.
31
31
 
32
32
  | Recipe | Use | Required floor |
33
33
  | ------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
34
34
  | `project-explainer` | Working explanation after project planning | one Markdown `hub` covering architecture, decisions, risks, phases, and validation |
35
- | `project-recap` | Final record after implementation and final review | HTML visual hub, architecture/system diagram, and deck governed by one set plan |
35
+ | `project-recap` | Final record after implementation and final review | one HTML navigational hub; diagrams, decks, and deep dives are adaptive expansions |
36
36
  | `program-recap` | Bird's-eye record of a multi-wave delivery program | one Markdown `hub` covering the wave map, outcomes, convention evolution, aggregate numbers, and follow-up ledger |
37
37
  | `engineer-tour` | Engineer-facing orientation to a codebase and its flow | one HTML-composed `explainer` covering orientation, architecture, execution flow, key code, and validation |
38
38
 
@@ -46,8 +46,8 @@ adding an OAT dependency.
46
46
  ### Project recap modes
47
47
 
48
48
  Project recaps default to `recapMode: artistic`. This mode uses the shared set
49
- plan and provider-neutral author seam to compose the required HTML hub,
50
- architecture view, and deck.
49
+ plan and provider-neutral author seam to compose the required HTML hub plus any
50
+ source-backed expansion that answers a distinct reader question.
51
51
 
52
52
  `recapMode: deterministic-markdown` is an explicit fallback for callers that
53
53
  need deterministic output. It preserves the same planned artifact portfolio and
@@ -63,16 +63,16 @@ artifact `type`, authoring path, brief, optional shell, and a mandatory
63
63
  `maxCount`. Every recipe also carries a mandatory `expansion.limits.maxArtifacts`
64
64
  that caps the whole expansion set; floor artifacts do not count against it.
65
65
 
66
- | Recipe | Profiles (max per profile) | `maxArtifacts` |
67
- | ------------------- | ------------------------------------------------ | -------------- |
68
- | `project-recap` | `status-view` 1, `rollout-view` 1, `deep-dive` 3 | 5 |
69
- | `program-recap` | `supporting-diagram` 3, `project-page` 12 | 12 |
70
- | `project-explainer` | `supporting-diagram` 4 | 4 |
71
- | `engineer-tour` | `supporting-diagram` 4 | 4 |
66
+ | Recipe | Profiles (max per profile) | `maxArtifacts` |
67
+ | ------------------- | ----------------------------------------------------------- | -------------- |
68
+ | `project-recap@2` | `supporting-diagram` 1, `walkthrough-deck` 1, `deep-dive` 3 | 5 |
69
+ | `program-recap` | `supporting-diagram` 3, `project-page` 12 | 12 |
70
+ | `project-explainer` | `supporting-diagram` 4 | 4 |
71
+ | `engineer-tour` | `supporting-diagram` 4 | 4 |
72
72
 
73
- For project recaps, optional status and rollout views require matching
74
- source-backed justifications, while `deep-dive` remains a Markdown
75
- `explainer`. Other recipes retain their recipe-owned diagram and project-page
73
+ For project recaps, every optional diagram, deck, or deep dive needs a distinct
74
+ reader question, supporting source evidence, and rationale for choosing that
75
+ medium. Other recipes retain their recipe-owned diagram and project-page
76
76
  profiles. Every declared type stays inside the frozen `manifest/v1` enum.
77
77
 
78
78
  ## Content authoring and review
@@ -116,6 +116,11 @@ author request, so an unattended author receives everything it needs in one
116
116
  payload. Changing a brief changes output expectations with no contract
117
117
  migration.
118
118
 
119
+ The bundled authoring prose covers typographic roles, hierarchy, composition,
120
+ density, medium leverage, template repetition, diagram semantics, and
121
+ cross-artifact cohesion. These remain editorial judgments rather than numeric
122
+ scores or deterministic layout checks.
123
+
119
124
  ### The planning and author seams
120
125
 
121
126
  Before authoring, one provider-neutral `planSet` callback produces the complete
@@ -125,15 +130,17 @@ portfolio. Every run also requires one provider-neutral author callback, in
125
130
  without one fails with `E_AUTHOR_REQUIRED`.
126
131
 
127
132
  The core invokes the author once per planned artifact with an
128
- `explainer-kit.author-request/v2` payload carrying the artifact identity and
133
+ `explainer-kit.author-request/v3` payload carrying the artifact identity and
129
134
  type, its authoring path, the inlined brief, the reconciled fact base, the
130
135
  resolved theme, the shell source for artistic artifacts, the immutable set
131
- context, the matching planned artifact, and bundled medium-specific authoring
132
- guidance. The installed skill is the complete unattended baseline; optional
136
+ context, the matching planned artifact, canonical artifact links, and bundled
137
+ medium-specific authoring guidance. Version 2 requests remain readable for
138
+ replay. The installed skill is the complete unattended baseline; optional
133
139
  provider capabilities can enhance composition but are not required. The core
134
- accepts only a schema-valid `explainer-kit.author-result/v2` containing exactly one of
135
- `content.markdown` or `content.html` plus non-secret provenance. Authored
136
- content is still checked for excessive verbatim overlap with the fact base.
140
+ accepts only a schema-valid `explainer-kit.author-result/v2` containing exactly
141
+ one of `content.markdown` or `content.html` plus non-secret provenance.
142
+ Authored content is still checked for excessive verbatim overlap with the fact
143
+ base.
137
144
 
138
145
  Direct callbacks and module entry points are first-class but transient: they
139
146
  never enter retained request contracts. See
@@ -143,9 +150,10 @@ planner, author, browser-session, and visual-critic boundaries.
143
150
  ### Planner-owned adaptive sets
144
151
 
145
152
  The set planner finalizes required and optional artifacts before authoring.
146
- Project recaps always contain a hub, architecture/system diagram, and deck;
147
- the planner may add only recipe-licensed optional views with a source-backed
148
- justification. Recipe and per-profile limits still bound the portfolio.
153
+ New project recaps always contain a navigational hub. The planner may add only
154
+ recipe-licensed optional diagrams, decks, or deep dives with a distinct reader
155
+ question, source evidence, and medium rationale. Recipe and per-profile limits
156
+ still bound the portfolio.
149
157
  Undeclared sources, conflicting ledger values, duplicate IDs, and unjustified
150
158
  optionals fail validation. Author results cannot add, remove, or replace
151
159
  artifacts.
@@ -188,11 +196,21 @@ evidence to an independent critic. Fixture sessions are test-only and are
188
196
  rejected in unattended production.
189
197
 
190
198
  A `correct` disposition permits one bounded correction and exactly one final
191
- review; there is no second correction or third review. Missing, forged,
199
+ review; there is no second correction or third review. The correction budget is
200
+ shared with the internal-link gate described below, so a `correct` disposition
201
+ is refused outright with `E_VISUAL_CORRECTION` when link validation already
202
+ spent the single bounded correction on this run. Missing, forged,
192
203
  cross-record-mismatched, or invalid evidence, a failed critic, or an unresolved
193
204
  correction ends as `built-needs-review`. Such output is retained for diagnosis
194
205
  but cannot become durable, finalized, archived, or published.
195
206
 
207
+ The critic reviews the whole set for typography, hierarchy, composition,
208
+ density, medium leverage, template repetition, diagram semantics, and
209
+ cross-artifact cohesion. It returns the existing provider-neutral result:
210
+ `pass` when no required correction remains or `correct` with concrete,
211
+ artifact-scoped actions for the bounded correction round. No numeric design
212
+ threshold is part of the contract.
213
+
196
214
  The approval record is also the durable source of truth for the resolved
197
215
  artifact set. It records every floor and accepted expansion artifact for all
198
216
  approval states, including pending and rejected, so a paused expanded run
@@ -221,6 +239,26 @@ Every legacy `ekrt1` token is rejected. A paused run created with the legacy
221
239
  format must restart to receive an authenticated token; editing retained package
222
240
  state cannot opt it into compatibility.
223
241
 
242
+ ### Internal-link validation
243
+
244
+ Every internal reference in the rendered set must resolve to a
245
+ manifest-declared target before the run can reach browser review. The gate runs
246
+ after render and uses a bounded tokenizer rather than a general HTML parser.
247
+ Relative references resolve from the current explicit file and must bind
248
+ exactly to the manifest/site tree, and a referenced fragment must resolve to
249
+ exactly one ID in its target document. Directory references, path traversal,
250
+ missing targets, missing fragments, ambiguous fragments, and unsafe schemes all
251
+ fail with `E_INTERNAL_REFERENCE`.
252
+
253
+ A failure gets one bounded correction round, re-rendered and revalidated. That
254
+ round is the same single budget the visual-review `correct` disposition uses —
255
+ whichever gate reaches it first consumes it. Once it is exhausted the run fails
256
+ hard: the QA stage is recorded `failed` with code-only evidence and the scrubbed
257
+ message `The qa stage failed.`, and the run is neither durability- nor
258
+ publication-eligible. No finding is retained, so nothing in the durable record
259
+ names the broken reference; the failure is attributed to the `link-validation`
260
+ evidence stage.
261
+
224
262
  ## Warnings and QA severity
225
263
 
226
264
  QA findings are split by severity, and the split is what lets thin content ship
@@ -296,9 +334,17 @@ Reviewed source and citation backlinks are absolute canonical GitHub blob URLs
296
334
  pinned to the exact 40-character commit revision and line range, so they
297
335
  survive project archival without resolving through a mutable branch or local
298
336
  checkout. Each recap also emits
299
- `site/initiatives/<slug>/catalog.json` from the finalized manifest. Its
300
- artifact IDs, types, paths, URLs, and source backlinks must remain in exact
301
- manifest parity; authors do not hand-maintain the catalog.
337
+ `site/initiatives/<slug>/catalog.json` from the finalized manifest, versioned
338
+ as `explainer-kit.initiative-catalog/v2`. Its artifact IDs, types, paths,
339
+ URLs, and source backlinks must remain in exact manifest parity; authors do
340
+ not hand-maintain the catalog. The catalog's `publicVerification` field is a
341
+ **policy marker, never an outcome**: `required` when the run's public access
342
+ policy calls for anonymous URL verification, `skipped-by-policy` for
343
+ protected destinations. It records what the publication policy was — the
344
+ per-artifact verification outcomes live in `publish-receipt.json`.
345
+ Compatibility is regenerate-only: consumers parse the declared version, and
346
+ no v1 read path exists because no released consumer could verify v1 catalog
347
+ evidence.
302
348
 
303
349
  `manifest.immutableHashes` covers the exact retained bytes for
304
350
  `run-request.json`, content approval, fact-base JSON and Markdown, declared
@@ -322,12 +368,25 @@ Build success and durability are separate:
322
368
 
323
369
  The core verifies caller-supplied commit or publish evidence; it never creates
324
370
  Git commits. Publishing is always explicitly requested and human-gated. The
325
- public `s3-static` connector validates corresponding S3 and HTTPS roots with a
326
- run-unique sentinel, uploads only manifest-declared `site/` files, verifies the
327
- content type and SHA-256 response bytes at public URLs, and writes
328
- `publish-receipt.json`. Public roots cannot contain credentials, queries, or
329
- fragments. Publishing is additive and does not run a root-wide destructive
330
- sync.
371
+ public `s3-static` connector validates each S3 and HTTPS root independently and
372
+ proves the destination with a run-unique sentinel, uploads only
373
+ manifest-declared `site/` files, and writes `publish-receipt.json`.
374
+ Verification depends on the declared `publicAccess` policy: in `public` mode
375
+ the connector anonymously fetches each published URL and compares content
376
+ type and SHA-256 response bytes; in `protected` mode it verifies object
377
+ integrity through authenticated S3 hashing instead, and every receipt entry
378
+ records `publicVerification: skipped-protected` so the skipped anonymous
379
+ check is visible rather than implied.
380
+
381
+ Root screening is strict on both roots: no credentials, queries, or
382
+ fragments; no whitespace, C0/C1 control characters, or backslashes; and the
383
+ gate applies to every publish-request and publish-receipt contract version
384
+ rather than being pinned to one version string. Public roots must be HTTPS
385
+ and must not address loopback, link-local, or private networks, and
386
+ verification fetches refuse redirects (`redirect: 'error'`) — see the
387
+ [publication environment variables](/docs/cli-utilities/configuration#explainer-publication-environment-variables)
388
+ for the explicit private-root opt-in and its durable receipt trace.
389
+ Publishing is additive and does not run a root-wide destructive sync.
331
390
 
332
391
  Release validation drives the bounded curated-style/template matrix in a real
333
392
  installed Chromium browser and retains machine-readable viewport, clipping,
@@ -375,8 +434,9 @@ typed adapter settings.
375
434
  Private integrations use the core boundary directly: resolve private inputs
376
435
  before the run, construct one versioned request, invoke the core once, then
377
436
  publish or link the versioned manifest after the run. Wrapper acceptance reads
378
- the complete post-run `PublishReceiptV1`, verifies every manifest artifact and
379
- the core run ID, and rejects foreign or stale receipts. Presets, private source
437
+ the complete post-run `publish-receipt/v2`, verifies every manifest artifact
438
+ and the core run ID, and rejects foreign or stale receipts; `publish-receipt/v1`
439
+ remains readable for replay of older runs only. Presets, private source
380
440
  systems, external-document synchronization, and personal destinations remain
381
441
  wrapper-owned.
382
442
 
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.2.30",
3
- "docs-config": "0.2.30",
4
- "docs-theme": "0.2.30",
5
- "docs-transforms": "0.2.30"
2
+ "cli": "0.2.32",
3
+ "docs-config": "0.2.32",
4
+ "docs-theme": "0.2.32",
5
+ "docs-transforms": "0.2.32"
6
6
  }