@awebai/oats 0.29.4 → 0.30.1

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 (263) hide show
  1. package/README.md +12 -6
  2. package/bin/oats.mjs +194 -50
  3. package/docs/capabilities.md +160 -171
  4. package/docs/capability-manifest.schema.json +6 -11
  5. package/docs/configuration.md +213 -64
  6. package/docs/design/2026-09-16-knowledge-capability-contract.md +36 -50
  7. package/docs/design/2026-09-23-workspace-module-contracts.md +377 -544
  8. package/docs/design/2026-09-26-okf-knowledge-operations.md +132 -357
  9. package/docs/design/2026-09-27-team-model-v2.md +97 -117
  10. package/docs/design/2026-09-28-automations-trust.md +38 -0
  11. package/docs/design/2026-09-28-soul-launch-preference.md +63 -0
  12. package/docs/design/HISTORY.md +65 -0
  13. package/docs/design/README.md +23 -54
  14. package/docs/desktop-cli-api.md +1787 -1777
  15. package/docs/desktop.md +30 -91
  16. package/docs/execution-targets.md +146 -292
  17. package/docs/first-team.md +31 -17
  18. package/docs/implementation.md +77 -288
  19. package/docs/integrations.md +118 -320
  20. package/docs/knowledge-capability-authoring.md +25 -52
  21. package/docs/knowledge-reference/acceptance.md +3 -3
  22. package/docs/knowledge-reference/adoption.md +1 -1
  23. package/docs/knowledge-reference/harvester.md +2 -2
  24. package/docs/knowledge-reference/package-craft.md +3 -3
  25. package/docs/knowledge-reference/provider-mapping.md +3 -6
  26. package/docs/knowledge-reference/reader-capture.md +3 -3
  27. package/docs/knowledge-theory.md +62 -166
  28. package/docs/knowledge.md +225 -404
  29. package/docs/layers.md +42 -97
  30. package/docs/oats-local.schema.json +58 -5
  31. package/docs/oats-membership.schema.json +1 -8
  32. package/docs/oats-package.schema.json +5 -5
  33. package/docs/oats-workspace.schema.json +8 -22
  34. package/docs/official-catalog.md +25 -28
  35. package/docs/packages.md +45 -63
  36. package/docs/plans/0.30-close-out.md +83 -0
  37. package/docs/release-lane.md +82 -0
  38. package/docs/release-notes/oats-framework-v1.1.3.md +10 -8
  39. package/docs/release-notes/v0.19.0.md +48 -147
  40. package/docs/release-notes/v0.19.1.md +2 -3
  41. package/docs/release-notes/v0.19.3.md +2 -15
  42. package/docs/release-notes/v0.20.0.md +0 -15
  43. package/docs/release-notes/v0.22.0.md +71 -138
  44. package/docs/release-notes/v0.22.1.md +42 -90
  45. package/docs/release-notes/v0.22.10.md +1 -1
  46. package/docs/release-notes/v0.22.11.md +1 -47
  47. package/docs/release-notes/v0.22.12.md +4 -13
  48. package/docs/release-notes/v0.22.13.md +1 -42
  49. package/docs/release-notes/v0.22.14.md +3 -11
  50. package/docs/release-notes/v0.22.15.md +1 -46
  51. package/docs/release-notes/v0.22.16.md +6 -8
  52. package/docs/release-notes/v0.22.18.md +1 -99
  53. package/docs/release-notes/v0.22.19.md +3 -14
  54. package/docs/release-notes/v0.22.2.md +6 -15
  55. package/docs/release-notes/v0.22.3.md +0 -1
  56. package/docs/release-notes/v0.22.4.md +1 -14
  57. package/docs/release-notes/v0.22.5.md +2 -12
  58. package/docs/release-notes/v0.22.6.md +0 -3
  59. package/docs/release-notes/v0.23.0.md +9 -25
  60. package/docs/release-notes/v0.23.1.md +9 -25
  61. package/docs/release-notes/v0.23.2.md +2 -4
  62. package/docs/release-notes/v0.24.0.md +56 -97
  63. package/docs/release-notes/v0.24.1.md +7 -11
  64. package/docs/release-notes/v0.24.10.md +34 -45
  65. package/docs/release-notes/v0.24.11.md +12 -20
  66. package/docs/release-notes/v0.24.12.md +35 -48
  67. package/docs/release-notes/v0.24.13.md +34 -41
  68. package/docs/release-notes/v0.24.2.md +9 -13
  69. package/docs/release-notes/v0.24.3.md +7 -11
  70. package/docs/release-notes/v0.24.4.md +6 -6
  71. package/docs/release-notes/v0.24.5.md +6 -10
  72. package/docs/release-notes/v0.24.6.md +2 -5
  73. package/docs/release-notes/v0.24.7.md +46 -75
  74. package/docs/release-notes/v0.24.8.md +58 -96
  75. package/docs/release-notes/v0.24.9.md +38 -54
  76. package/docs/release-notes/v0.25.0.md +59 -76
  77. package/docs/release-notes/v0.25.1.md +57 -81
  78. package/docs/release-notes/v0.25.2.md +51 -70
  79. package/docs/release-notes/v0.25.3.md +11 -13
  80. package/docs/release-notes/v0.25.4.md +9 -13
  81. package/docs/release-notes/v0.25.5.md +3 -5
  82. package/docs/release-notes/v0.25.6.md +20 -29
  83. package/docs/release-notes/v0.25.7.md +5 -7
  84. package/docs/release-notes/v0.25.8.md +26 -39
  85. package/docs/release-notes/v0.26.0.md +175 -646
  86. package/docs/release-notes/v0.27.0.md +4 -5
  87. package/docs/release-notes/v0.27.1.md +4 -6
  88. package/docs/release-notes/v0.27.2.md +1 -1
  89. package/docs/release-notes/v0.28.0.md +57 -124
  90. package/docs/release-notes/v0.29.0.md +89 -208
  91. package/docs/release-notes/v0.29.1.md +1 -1
  92. package/docs/release-notes/v0.29.2.md +3 -4
  93. package/docs/release-notes/v0.30.0.md +205 -0
  94. package/docs/release-notes/v0.30.1.md +123 -0
  95. package/docs/schedules.md +280 -363
  96. package/docs/servers.md +99 -117
  97. package/docs/soul.schema.json +2 -9
  98. package/docs/souls-and-instances.md +145 -158
  99. package/docs/workspaces.md +137 -215
  100. package/lib/automations.mjs +21 -6
  101. package/lib/core.mjs +226 -74
  102. package/lib/instance-events.mjs +1 -1
  103. package/lib/instance-inspect.mjs +109 -34
  104. package/lib/instance-lifecycle.mjs +14 -1
  105. package/lib/instance-resolution.mjs +26 -27
  106. package/lib/launch-preference.mjs +87 -0
  107. package/lib/materialize.mjs +3 -3
  108. package/lib/packages.mjs +1 -1
  109. package/lib/resolve.mjs +30 -88
  110. package/lib/schedule.mjs +1 -1
  111. package/lib/teams-verbs.mjs +195 -0
  112. package/lib/teams.mjs +190 -0
  113. package/lib/triggers.mjs +2 -2
  114. package/lib/workspace.mjs +54 -147
  115. package/package-catalog.json +10 -16
  116. package/package.json +1 -3
  117. package/skills/oats-getting-started/SKILL.md +25 -13
  118. package/capabilities/oats-authoring/LICENSE +0 -21
  119. package/capabilities/oats-authoring/oats-package.json +0 -11
  120. package/capabilities/oats-authoring/oats.json +0 -12
  121. package/capabilities/oats-authoring/skills/integration-authoring/SKILL.md +0 -84
  122. package/capabilities/oats-authoring/skills/skill-craft/SKILL.md +0 -109
  123. package/capabilities/oats-authoring/skills/soul-craft/SKILL.md +0 -116
  124. package/capabilities/oats-aweb/bin/oats-aweb-binding.mjs +0 -11
  125. package/capabilities/oats-aweb/bin/oats-aweb.mjs +0 -1338
  126. package/capabilities/oats-aweb/injects/aweb.md +0 -47
  127. package/capabilities/oats-aweb/lib/binding-wire.mjs +0 -356
  128. package/capabilities/oats-aweb/lib/captured-execution.mjs +0 -91
  129. package/capabilities/oats-aweb/lib/captured-native.mjs +0 -91
  130. package/capabilities/oats-aweb/lib/grant-custody.mjs +0 -38
  131. package/capabilities/oats-aweb/lib/invocation-shape.mjs +0 -135
  132. package/capabilities/oats-aweb/lib/portable-binding.mjs +0 -146
  133. package/capabilities/oats-aweb/lib/session-readiness.mjs +0 -56
  134. package/capabilities/oats-aweb/lib/wake-receive.mjs +0 -56
  135. package/capabilities/oats-aweb/oats.json +0 -208
  136. package/capabilities/oats-aweb/skills/LICENSE +0 -21
  137. package/capabilities/oats-aweb/skills/VENDORED.md +0 -31
  138. package/capabilities/oats-aweb/skills/aweb-identity/SKILL.md +0 -201
  139. package/capabilities/oats-aweb/skills/aweb-messaging/SKILL.md +0 -161
  140. package/capabilities/oats-aweb/skills/aweb-messaging/references/messaging-scenarios.md +0 -61
  141. package/capabilities/oats-aweb/skills/aweb-team-membership/SKILL.md +0 -116
  142. package/capabilities/oats-aweb/skills/aweb-team-membership/references/team-membership-reference.md +0 -74
  143. package/capabilities/oats-aweb/skills/oats-aweb/SKILL.md +0 -216
  144. package/capabilities/oats-jira/bin/oats-jira.mjs +0 -40
  145. package/capabilities/oats-jira/injects/jira.md +0 -10
  146. package/capabilities/oats-jira/oats.json +0 -22
  147. package/capabilities/oats-jira/skills/jira-tasks/SKILL.md +0 -179
  148. package/capabilities/oats-linear/bin/oats-linear-hook.mjs +0 -34
  149. package/capabilities/oats-linear/bin/oats-linear.mjs +0 -344
  150. package/capabilities/oats-linear/injects/linear.md +0 -8
  151. package/capabilities/oats-linear/oats.json +0 -24
  152. package/capabilities/oats-linear/skills/linear-tasks/SKILL.md +0 -223
  153. package/capabilities/oats-okf/bin/oats-okf-binding.mjs +0 -14
  154. package/capabilities/oats-okf/bin/oats-okf.mjs +0 -209
  155. package/capabilities/oats-okf/injects/okf.md +0 -42
  156. package/capabilities/oats-okf/lib/binding-wire.mjs +0 -348
  157. package/capabilities/oats-okf/lib/captured-worker.mjs +0 -109
  158. package/capabilities/oats-okf/lib/config.mjs +0 -124
  159. package/capabilities/oats-okf/lib/consult.mjs +0 -518
  160. package/capabilities/oats-okf/lib/harvest-status.mjs +0 -88
  161. package/capabilities/oats-okf/lib/harvest-switch.mjs +0 -94
  162. package/capabilities/oats-okf/lib/inspection.mjs +0 -119
  163. package/capabilities/oats-okf/lib/invocation-context.mjs +0 -111
  164. package/capabilities/oats-okf/lib/invocation-shape.mjs +0 -135
  165. package/capabilities/oats-okf/lib/io.mjs +0 -118
  166. package/capabilities/oats-okf/lib/migration.mjs +0 -137
  167. package/capabilities/oats-okf/lib/okf-validate.mjs +0 -123
  168. package/capabilities/oats-okf/lib/portable-binding.mjs +0 -199
  169. package/capabilities/oats-okf/lib/source-contract.mjs +0 -46
  170. package/capabilities/oats-okf/lib/sources.mjs +0 -424
  171. package/capabilities/oats-okf/lib/stores.mjs +0 -473
  172. package/capabilities/oats-okf/lib/worker.mjs +0 -497
  173. package/capabilities/oats-okf/oats.json +0 -148
  174. package/capabilities/oats-okf/schemas/okf-base.schema.json +0 -46
  175. package/capabilities/oats-okf/schemas/okf-bindings.schema.json +0 -112
  176. package/capabilities/oats-okf/schemas/okf-portable-declaration.schema.json +0 -87
  177. package/capabilities/oats-okf/schemas/okf-portable-payload.schema.json +0 -113
  178. package/capabilities/oats-okf/schemas/okf-soul.schema.json +0 -37
  179. package/capabilities/oats-okf/skills/okf-consultation/SKILL.md +0 -144
  180. package/capabilities/oats-okf/skills/okf-consultation/references/consult.md +0 -86
  181. package/capabilities/oats-okf/skills/okf-instance-knowledge/SKILL.md +0 -104
  182. package/capabilities/oats-okf-harvest/bin/okf-harvest.mjs +0 -140
  183. package/capabilities/oats-okf-harvest/injects/harvester.md +0 -12
  184. package/capabilities/oats-okf-harvest/oats.json +0 -26
  185. package/capabilities/oats-okf-harvest/skills/knowledge-harvest/SKILL.md +0 -168
  186. package/capabilities/oats-okf-harvest/skills/knowledge-theory/SKILL.md +0 -192
  187. package/capabilities/oats-okf-harvest/skills/okf-authoring/SKILL.md +0 -151
  188. package/capabilities/oats-okf-harvest/skills/okf-authoring/scripts/okf-validate.mjs +0 -123
  189. package/capabilities/oats-okf-maintenance/bin/okf-maintenance.mjs +0 -170
  190. package/capabilities/oats-okf-maintenance/injects/maintainer.md +0 -12
  191. package/capabilities/oats-okf-maintenance/lib/provenance.mjs +0 -50
  192. package/capabilities/oats-okf-maintenance/oats.json +0 -21
  193. package/capabilities/oats-okf-maintenance/skills/knowledge-review/SKILL.md +0 -159
  194. package/capabilities/oats-okf-maintenance/skills/knowledge-theory/SKILL.md +0 -192
  195. package/capabilities/oats-okf-maintenance/skills/okf-authoring/SKILL.md +0 -151
  196. package/capabilities/oats-okf-maintenance/skills/okf-authoring/scripts/okf-validate.mjs +0 -123
  197. package/capabilities/oats-okf-maintenance/skills/okf-trigger-setup/SKILL.md +0 -146
  198. package/capabilities/oats-review/injects/review.md +0 -69
  199. package/capabilities/oats-review/oats.json +0 -10
  200. package/capabilities/oats-review/skills/code-review/SKILL.md +0 -44
  201. package/capabilities/oats-review/skills/security-review/SKILL.md +0 -59
  202. package/docs/conventions.md +0 -90
  203. package/docs/design/2026-09-07-architecture-reassessment.md +0 -131
  204. package/docs/design/2026-09-07-desktop-souls-capabilities.md +0 -50
  205. package/docs/design/2026-09-07-mobile-agent-management-proposal.md +0 -228
  206. package/docs/design/2026-09-08-expert-assisted-deployment-proposal.md +0 -558
  207. package/docs/design/2026-09-13-knowledge-and-memory-direction.md +0 -744
  208. package/docs/design/2026-09-13-knowledge-implementation.md +0 -127
  209. package/docs/design/2026-09-13-knowledge-location-contract.md +0 -340
  210. package/docs/design/2026-09-14-artifact-retention-contract.md +0 -190
  211. package/docs/design/2026-09-14-portable-souls-and-git-workspaces.md +0 -708
  212. package/docs/design/2026-09-14-portable-souls-contract-amendments.md +0 -85
  213. package/docs/design/2026-09-14-portable-souls-explainer.md +0 -750
  214. package/docs/design/2026-09-15-captured-dispatch.md +0 -127
  215. package/docs/design/2026-09-15-captured-resolution-records.md +0 -143
  216. package/docs/design/2026-09-15-package-preparation.md +0 -100
  217. package/docs/design/2026-09-15-portable-data-contract.md +0 -121
  218. package/docs/design/2026-09-15-portable-declarations.md +0 -189
  219. package/docs/design/2026-09-15-portable-souls-handoff.md +0 -150
  220. package/docs/design/2026-09-15-portable-souls-implementation.md +0 -417
  221. package/docs/design/2026-09-15-selection-lock-and-approval.md +0 -122
  222. package/docs/design/2026-09-15-source-observation.md +0 -119
  223. package/docs/design/2026-09-16-captured-admission.md +0 -77
  224. package/docs/design/2026-09-16-captured-helper-dispatch.md +0 -105
  225. package/docs/design/2026-09-16-captured-launch-inputs.md +0 -42
  226. package/docs/design/2026-09-16-command-profile-preparation.md +0 -86
  227. package/docs/design/2026-09-16-fresh-install-first-rollout.md +0 -47
  228. package/docs/design/2026-09-16-fresh-operator-walkthrough.md +0 -282
  229. package/docs/design/2026-09-16-messaging-capability-contract.md +0 -59
  230. package/docs/design/2026-09-16-portable-migration-evidence.md +0 -158
  231. package/docs/design/2026-09-16-portable-onboarding.md +0 -179
  232. package/docs/design/2026-09-16-prepare-request-transport.md +0 -26
  233. package/docs/design/2026-09-16-provider-binding-codecs.md +0 -98
  234. package/docs/design/2026-09-16-provider-binding-wire.md +0 -274
  235. package/docs/design/2026-09-17-capability-helper-input-contract.md +0 -95
  236. package/docs/design/2026-09-17-captured-backend-parity.md +0 -53
  237. package/docs/design/2026-09-17-captured-native-start.md +0 -58
  238. package/docs/design/2026-09-17-portable-boundary-hookup.md +0 -19
  239. package/docs/design/2026-09-17-portable-boundary-resources.md +0 -52
  240. package/docs/design/2026-09-17-public-captured-start.md +0 -108
  241. package/docs/design/2026-09-17-public-prepare-request.md +0 -90
  242. package/docs/design/2026-09-18-captured-pi-host.md +0 -205
  243. package/docs/design/2026-09-18-first-cut-release-checklist.md +0 -131
  244. package/docs/design/2026-09-18-herdr-protocol-compatibility.md +0 -60
  245. package/docs/design/2026-09-20-redesign-program-board.md +0 -142
  246. package/docs/design/2026-09-20-workspace-and-portable-adoption-plan.md +0 -289
  247. package/docs/design/2026-09-20-workspace-onboarding-public.md +0 -207
  248. package/docs/design/2026-09-22-desktop-parity-seams.md +0 -58
  249. package/docs/design/2026-09-23-simplified-workspace-model.md +0 -711
  250. package/docs/design/2026-09-23-workspace-v2-implementation-plan.md +0 -65
  251. package/docs/design/2026-09-24-desktop-phase-f-boundary.md +0 -242
  252. package/docs/design/2026-09-24-phase-d-plan.md +0 -305
  253. package/docs/design/2026-09-25-teams-contract.md +0 -258
  254. package/docs/design/2026-09-26-desktop-design-brief-architecture.md +0 -241
  255. package/docs/design/desktop-ux-plan.md +0 -362
  256. package/docs/design/launch-configurations.md +0 -168
  257. package/docs/design/okf-mirror-provenance.md +0 -105
  258. package/docs/design/operations-contract.md +0 -141
  259. package/docs/oats-member.schema.json +0 -38
  260. package/skills/integration-authoring/SKILL.md +0 -84
  261. package/skills/oats-support/SKILL.md +0 -79
  262. package/skills/skill-craft/SKILL.md +0 -109
  263. package/skills/soul-craft/SKILL.md +0 -116
@@ -1,670 +1,199 @@
1
1
  # OATS 0.26.0
2
2
 
3
- The workspace model is the only model the kernel knows ("v2 becomes the
4
- classic"). The 0.24-era classic path is removed, not flagged: a 0.24.x kernel
5
- keeps running 0.24.x deployments, and a 0.25.x deployment is already v2
6
- (the 0.24 → 0.25 rebuild guide is removed in this release; see
7
- [Upgrading from 0.25](#upgrading-from-025)).
3
+ The workspace model is the only model the kernel knows. The 0.24-era classic
4
+ path is removed, not flagged: a 0.24.x kernel keeps running 0.24.x
5
+ deployments, and a 0.25.x deployment is already on the workspace model. See
6
+ [Upgrading from 0.25](#upgrading-from-025).
8
7
 
9
8
  ## Removed
10
9
 
11
- - **The captured/portable path** (0.24–0.25's `oats prepare`, captured
12
- resolutions, `--deployment --resolution` dispatch, the pi SDK host and
13
- versioned schedules; lead decisions on (e)). Nothing on the workspace path
14
- used it, as coverage of the v2 flows showed. What is left of it is typed
15
- refusals, none falling back to the workspace path:
16
- - The selectors `--deployment`, `--resolution` and `--artifact-set`, and an
17
- inherited `OATS_DEPLOYMENT` / `OATS_RESOLUTION`, are refused by every
18
- command except `version` (`E_UNSUPPORTED_MODE`, `details.selector` or
19
- `details.inherited`). That includes the captured `oats trust
20
- --deployment|--artifact-set`.
21
- - `oats prepare` and `oats inspect --request` are removed verbs
22
- (`E_UNKNOWN_COMMAND`, `details: {removed, replacement}`): `oats onboard` /
23
- `oats sync` set a workspace up, and `oats spawn <soul> --preview` shows
24
- what a spawn would resolve.
25
- - `oats version --json` no longer carries `capturedDispatchApi` or
26
- `capturedDispatchActions`.
27
- - **Captured homes** (an `instance.json` recording `executionBinding`,
28
- `incarnationId` or `captured`) have no 0.26 runtime. `oats status` and
29
- `oats doctor` report them once as the problem **`legacy-captured-home`**
30
- (JSON `problems[]`: `{instances, homes, message}`). Session start/restart,
31
- `inspect|readiness|operation --home` and in-home commands refuse them
32
- (`E_UNSUPPORTED_MODE`, `details: {home, captured: true}`). **`oats retire`
33
- works, but their captured retire hooks do not run:** the result's
34
- `warnings[]` (also printed by the human output) names each capability whose
35
- spawn hook ran, since identities/memberships it created are not revoked —
36
- remove them with the provider's own tooling.
37
- - **Captured schedule definitions** (`definitionVersion`, `recurrencePolicy`,
38
- `execution`, `preparation`) are refused by `schedule add|update`
39
- (`E_SCHEDULE_INVALID`, the key as `field`), locally and before any
40
- `--server` forwarding. A command argv carrying a captured selector is
41
- refused too. A stored one is `invalid` on its own job and never runs, and a
42
- captured attempt or job lock left by 0.25 is reported on its job and never
43
- run or adopted: `oats schedule remove --force <id>` clears it (a held lock
44
- keeps its launch slot until then). The run outcome `blocked` is no longer
45
- produced.
46
- - **Manifest keys:** `helperInjection` and hook `inputs` are accepted and
47
- ignored (existing manifests still load).
48
- - **Public core exports removed with it** (no in-repo consumer):
49
- `capabilityArtifactIntegrity`, `OATS_LOCK_FILE`, `CAPABILITIES_DIRNAME`,
50
- `INSTALLED_SUBDIR`, `CAPABILITY_ID_RE`, `isMaterializedCapabilityId`,
51
- `capabilityIdViolation`, `CAPABILITY_INSTALLATION_FILE`,
52
- `normalizePackagePath`, `validateLockEntry`, `validateCapabilityLockEntry`,
53
- `verifyCapabilityInstallation`, `loadPackageManifestAt`,
54
- `assertCapabilitySelfContained`, `materializeCapabilityDeps`,
55
- `platformVariantLockPackages`, `isCanonicalTemplatePath`, and every
56
- captured/portable export (`startCapturedInstanceSession`,
57
- `prepareCapturedComposition`, `loadCapturedDispatch`, …).
58
- - **Schemas removed:** `portable`, `captured-resolution`,
59
- `captured-invocation-context`, `execution-capsule`, `artifact-approvals`,
60
- `oats-lock-v3` (the captured *selection* lock, never the workspace lock) and
61
- `oats-lock` (lockfileVersion 2), plus `provider-check-input` (the captured
62
- check request; the workspace readiness request is documented in
63
- [capabilities](../capabilities.md#readiness-check-bindingcheck)). The design
64
- notes `package-engine-contract.md` and `package-runtime-api.md` are deleted.
65
- - Errors from kernel metadata reads say "metadata file", not "portable
66
- metadata".
67
- - **Kernel skills and injects** (human decision on D7): `oats-portable`,
68
- `oats-portable-artifacts` and the injects `oats-portable`,
69
- `portable-instance-boundary` and `portable-work-directory` are deleted, and so
70
- are the kernel's own **`oats` skill** and **`injects/oats.md`** ("You run on
71
- OATS"): the `oats.core` capability (`oats.framework` package, the workspace
72
- default) ships the operating skills (`oats-operate`, `oats-souls`) and that
73
- briefing, and the workspace path already composed only its copy. A soul
74
- without `oats.core` gets no OATS operating instructions; `oats doctor --soul`
75
- says so. The kernel keeps `instance-boundary`, the `work-*` briefings and the
76
- ambient `oats-getting-started`.
77
-
78
- - **Package approval** (human decision, 2026-09-24). People install a package
79
- only when they trust it: declaring it in the workspace's `packages:` IS the
80
- trust decision, so there is no second, per-version approval step.
81
- - `oats sync` resolves, fetches, verifies integrity, writes the lock and exits
82
- `0` on success. No exit `2` for pending approvals, no interactive prompt, no
83
- `approvalNeeded` in the report and none on `changes[]` rows.
84
- `oats sync --approve …` is `E_BAD_ARGS` naming the decision.
85
- - `oats onboard` has no approval-pending outcome and no "approve first" hint.
86
- - The lock (v3) drops the per-entry `approved` record. A lock that still
87
- carries it is read with the field ignored, and the next write drops it.
88
- **A kernel before 0.26.0 cannot read a lock 0.26.0 wrote** (`E_LOCK_SCHEMA`
89
- on the missing `approved`): keep every kernel that reads one deployment on
90
- 0.26.0 or later.
91
- - The lock still pins each package to its exact commit and content integrity.
92
- `oats sync` refuses a moved tag, drifted content and a lock whose capability
93
- list no longer matches the package (`E_PACKAGE_INTEGRITY`) —
94
- reproducibility, not approval.
95
- **Where integrity is checked:** `oats sync` recomputes each package's
96
- content digest and refuses drift. At spawn, the kernel checks the lock's
97
- capability list against the package and trusts the locked commit plus
98
- materialize's fetch-versus-copy self-check. The lock's integrity is
99
- recorded in each module's `from`, not recomputed per spawn. (The removed
100
- per-spawn executables-digest check was an approval binding, not an
101
- integrity guarantee.)
102
- - Spawn, `--preview` and operator dispatch never raise `E_PACKAGE_UNAPPROVED`;
103
- the executables-digest gate is gone. At spawn a package capability must come
104
- from a package the workspace **still declares** (a stale lock entry for a
105
- package removed from `packages:` is `E_PACKAGE_MISSING { reason:
106
- "undeclared" }` until `oats sync`), and the lock's capability list must match
107
- what the package declares at the locked commit (`E_PACKAGE_INTEGRITY { why:
108
- "capabilities" }`). A package capability agent is found only in a declared
109
- package.
110
- - `oats workspace status` loses its `approval` object and column; `oats
111
- capabilities` package rows lose `approved`; `oats doctor` prints each locked
112
- package's integrity instead of its approval.
113
- - `oats version --json` advertises `packages-no-approval`. `syncApi`,
114
- `workspaceStatusApi` and `capabilitiesApi` are NOT bumped: a consumer that
115
- reads the removed fields gates on this feature string.
116
- - **The `soul` link in instance homes.** A home no longer carries
117
- `<home>/soul`: its composed `AGENTS.md` already holds the soul's
118
- instructions. The soul directory an instance incarnates is recorded as
119
- `instance.json` `soulDir` (a workspace soul's per-commit copy
120
- `<deployment>/agents/<soul>/souls/<commit12>`, or the read-only soul inside a
121
- capability package) and is handed to every classic lifecycle hook — spawn,
122
- launch, retire — and to every capability command dispatched inside a home as
123
- `OATS_SOUL`. Launch
124
- and retire hooks, and in-home commands such as `oats okf harvest`, previously
125
- received no `OATS_SOUL`; `oats operation run`
126
- previously handed the swappable `agents/<soul>/soul` pointer. `oats session
127
- recompose` reads the recorded `soulDir`. A spawn that is rolled back into
128
- quarantine records the soul in its cleanup descriptor, so a retried retire
129
- hook sees the spawn's soul. A capability command dispatched with no recorded
130
- soul gets no `OATS_SOUL`, never one inherited from the invoking process.
131
- - **Homes spawned before 0.26.0** record no `soulDir`. They keep their
132
- existing `soul` link (0.26.0 neither reads nor removes it). Their retire
133
- hooks get the soul pointer `agents/<soul>/soul` (today's soul, not
134
- necessarily the spawn's commit). They are degraded: their launch hooks and
135
- in-home commands get no `OATS_SOUL` (a provider that requires it, such as
136
- oats.okf 2.1.5, refuses with `E_OATS_SOUL_MISSING`), and `oats session
137
- recompose` refuses them (`E_SOUL_UNKNOWN`). Re-spawn to get a recorded
138
- `soulDir`.
139
-
10
+ - **The captured/portable path** (`oats prepare`, captured resolutions,
11
+ `--deployment --resolution` dispatch, the pi SDK host, versioned schedules).
12
+ What is left are typed refusals:
13
+ - The selectors `--deployment`, `--resolution`, `--artifact-set` and an
14
+ inherited `OATS_DEPLOYMENT` / `OATS_RESOLUTION` are `E_UNSUPPORTED_MODE`
15
+ for every command but `version`. `oats prepare` and `oats inspect
16
+ --request` are `E_UNKNOWN_COMMAND`, naming `oats onboard` / `oats sync` and
17
+ `oats spawn <soul> --preview`.
18
+ - **Captured homes** are reported as the problem `legacy-captured-home` and
19
+ refused by start, restart, `--home` reads and in-home commands. `oats
20
+ retire` works but runs no captured retire hook; its `warnings[]` name the
21
+ capabilities whose identities to revoke with the provider's tooling.
22
+ - **Captured schedule keys** are refused by `schedule add|update`
23
+ (`E_SCHEDULE_INVALID`); a stored captured job or lock never runs until
24
+ `oats schedule remove --force <id>` clears it.
25
+ - Manifest keys `helperInjection` and hook `inputs` are accepted and
26
+ ignored. `oats version --json` drops `capturedDispatchApi` and
27
+ `capturedDispatchActions`. The captured/portable core exports, the
28
+ installed-tier and lock v2 helpers, and their schemas (including
29
+ `oats-lock` lockfileVersion 2 and `provider-check-input`) are removed.
30
+ - **Kernel skills, injects and the operational block.** The kernel's `oats`,
31
+ `oats-config`, `oats-packages` and portable skills, and its "You run on
32
+ OATS" and portable injects, are deleted. `oats.core` (the `oats.framework`
33
+ package, the workspace default) ships the operating skills and briefing,
34
+ `oats.setup` the setup skills. A soul without them gets no OATS operating
35
+ instructions (`oats doctor --soul` says so). The kernel keeps
36
+ `instance-boundary`, the `work-*` briefings and `oats-getting-started`.
37
+ - **Package approval.** Declaring a package in `packages:` is the trust
38
+ decision. `oats sync` exits `0` on success (no exit `2`, prompt or
39
+ `approvalNeeded`; `--approve` is `E_BAD_ARGS`), and `oats onboard` has no
40
+ approval step. `E_PACKAGE_UNAPPROVED` is gone. Lock v3 drops `approved`
41
+ (ignored on read, dropped on write). **A kernel before 0.26.0 cannot read a
42
+ lock 0.26.0 wrote** (`E_LOCK_SCHEMA`): keep every kernel of a deployment on
43
+ 0.26.0 or later. The lock still pins commit and content integrity
44
+ (`E_PACKAGE_INTEGRITY`); a package no longer declared is `E_PACKAGE_MISSING`
45
+ at spawn until `oats sync`. The `approval`/`approved` fields leave `oats
46
+ workspace status` and `oats capabilities`. Gate on the feature
47
+ `packages-no-approval`; the API integers are not bumped.
48
+ - **The `soul` link in instance homes.** `instance.json` records `soulDir`,
49
+ handed as `OATS_SOUL` to every spawn, launch and retire hook and to in-home
50
+ capability commands (launch and retire hooks and in-home commands had none
51
+ before). A command with no recorded soul gets no `OATS_SOUL`. Homes spawned
52
+ before 0.26.0 keep their link; their launch hooks and in-home commands get no
53
+ `OATS_SOUL` (oats.okf 2.1.5 refuses with `E_OATS_SOUL_MISSING`): re-spawn
54
+ them.
140
55
  - **Local souls and `local-agents/`.** A soul is a member repository's
141
- `souls/<name>` (`soul.yaml` + `AGENTS.md`); there are no machine-local souls.
142
- - **`oats create` is removed**: `E_UNKNOWN_COMMAND` naming the replacement
143
- (author `souls/<name>/soul.yaml` + `AGENTS.md` in a member repository, then
144
- `oats sync`). `--local`, `--type` and the `.gitignore` injection went with it.
145
- - **`oats spawn --instructions-file` and `--def-file`** (which wrote a local
146
- soul, including from a `.claude/agents` definition) are refused with
147
- `E_BAD_ARGS` naming the same replacement. `oats status` no longer lists
148
- importable definitions.
149
- - The kernel no longer composes the local-soul instruction block.
150
- - **`soul-scaffold` hooks are no longer run** (souls are authored in member
151
- repositories); manifests may still declare it until providers drop it.
152
- - **Capability-defined agents** (a package's or member module's `agents/`,
153
- such as the OKF harvester) now home at
154
- `<deployment>/agents/<agent>/instances/<name>`, like souls. That directory
155
- holds only `instances/`. A name that is both a workspace soul and a
156
- capability agent stays `E_SOUL_AMBIGUOUS`.
157
- - The agents root is found only as the closest `agents/` (or
158
- `PI_AGENTS_ROOT`); a `local-agents/` beside it no longer locates one.
159
- - **OAS scope probes.** `oats doctor` no longer looks for un-migrated OAS
160
- scope files, and the dead `docs/migration-from-oas.md` links went with the
161
- probe.
162
- - **The installed tier.** `oats doctor` loses its installed-packages section.
163
- The restore, remove, lock-migration and installed config-template readers
164
- are deleted with it.
165
- - **Classic verbs** (lead decision 3). Each answers a typed refusal naming
166
- its replacement:
167
- - `oats type` and `oats soul set` are removed verbs (`E_UNKNOWN_COMMAND`).
168
- A soul is edited in its member repository (`soul.yaml` + `AGENTS.md`),
169
- then `oats sync`; per-spawn choices are spawn flags or a launch
170
- configuration. `soul` no longer routes with `--server`.
171
- - `oats session recompose` is `E_UNKNOWN_COMMAND`, and the
172
- `session-recompose` feature is no longer advertised. The refresh path is
173
- a re-spawn: an instance never changes under itself.
174
- - `oats status --team` is `E_BAD_ARGS`: `oats status` in the deployment
175
- lists every instance, and `oats workspace status` shows the members.
176
- - **The classic answers of `oats inspect`, `oats readiness` and `oats
177
- operation run`** (lead decision 4). There is no v1 shape any more. With no
178
- `oats-local.yaml` in reach and no `--home` they answer `E_LOCAL_MISSING`; a
179
- `--home` whose `instance.json` records no `modules` (spawned by an earlier
180
- kernel) answers `E_UNSUPPORTED_MODE` (re-spawn it from the deployment); an
181
- unreadable `--home` answers `E_SESSION_UNKNOWN`. `--verify-signatures` is
182
- always `E_BAD_ARGS`, and the signature verifier is deleted.
183
-
184
- - **`oats-config.yaml` and the scope configuration chain** (lead decisions
185
- c3 1–7, 9). The kernel reads no `oats-config.yaml`. One found between a
186
- command's directory and its deployment (the directory holding
187
- `oats-local.yaml`) is refused, `E_CONFIG_BROKEN` (`reason:
188
- "legacy-config"`), naming where each key went; with no `oats-local.yaml` in
189
- reach, `E_LOCAL_MISSING` names the file as a 0.25 deployment's.
190
- `docs/oats-config.schema.json` is deleted (below). Each key:
191
- - **`capabilities:`** (`layers:`, `additive:`, targets, `from:`,
192
- `injection-override:`) and **`agent-types:`**: a soul's capabilities are
193
- the workspace's resolution — `oats-workspace.yaml` `defaults:` and each
194
- soul's `soul.yaml` `capabilities:` / slot keys, then `oats sync`.
195
- - **`team:`**: teams are `oats-workspace.yaml` `teams:` and a soul's
196
- `team:`. Hooks get the workspace facts only: `OATS_TEAM_SCOPE` (the
197
- deployment), `OATS_TEAM_ID` (the messaging payload's `team`),
198
- `OATS_TEAM_LABEL`, `OATS_WORKSPACE_NAME`, `OATS_WORKSPACE_KEY`;
199
- `OATS_TEAM_NAME` is always empty. Operator-level capability commands get
200
- the same five.
201
- - **`work-modes:`**: a soul's `work:` and the spawn flags decide the mode. A
202
- worktree `setup:` script no longer runs (run it yourself, or from a
203
- capability's spawn hook); `retirement-disposable:` is gone with it (a
204
- capability's manifest `retirement.disposable` still applies).
205
- - **`agents-md-injection:`**: removed. Instructions come from the soul and
206
- its modules' injects.
207
- - **`skill-overrides:`**: removed. A duplicate skill name is
208
- `E_SKILL_DUPLICATE`; there is no override.
209
- - **Scope `yolo:`**: removed. Yolo is `--yolo` on `oats spawn`, `session
210
- start` and `session restart`, or a launch configuration's `yolo`.
211
- - **`launch-configs:`**: moved to `oats-local.yaml` (see Changed).
212
- - **`oats:` `injection-override:`**: removed with the kernel's operational
213
- block (below).
214
- - **Scheduling a capability agent by name.** A `kind: "spawn"` schedule's
215
- `agent` is a soul under the deployment's `agents/` root only; the fallback
216
- to a capability-defined agent (a harvester, a reviewer) is gone with the
217
- config chain (`E_SCHEDULE_INVALID`, `agent: no soul named …`). Schedule what
218
- spawns it instead: a `kind: "command"` job running the capability's own
219
- command (for example `oats okf harvest --soul <soul>`), or a
220
- `kind: "operation"` job running the provider operation on the anchor home.
221
- - **Spawning without a workspace deployment.** `oats spawn` with no
222
- `oats-local.yaml` in reach is `E_LOCAL_MISSING` naming `oats onboard`
223
- (0.25 answered `E_NO_DEPLOYMENT`, which now means only a deployment whose
224
- `agents/` root is missing); the kernel's `spawnInstance` without a prepared resolution refuses the same
225
- way (`spawnInstanceAsync` with `prepared` is the one spawn).
226
- - **v1 soul fields.** A soul's `runtime`, `model`, `backend`, `repo`, `yolo`,
227
- `launch-config`, `children` and `requires:` are not read (the v2 soul schema
228
- already refuses them at discovery; lead decision c3 Q6). They are spawn and
229
- host choices: `--runtime`, `--model`, `--backend`, `--repo`, `--yolo`,
230
- `--launch-config` / `oats-local.yaml` `launch-configs:`, and
231
- `--allow-child-spawns` / `--no-child-spawns` (a recorded child-spawn policy's
232
- origin is `spawn-option` or `default`, never `soul`). An attached instance
233
- works in its work tree owner's recorded repository. A capability agent's own
234
- `soul.yaml` (for example `oats.review`'s reviewer) still names its default
235
- `runtime`, `model` and `work`.
236
- - **The kernel's operational block and bundled skills** (lead decision c3 9).
237
- A soul whose resolution has no `oats.core` or `oats.setup` module no longer
238
- gets the kernel's "You run on OATS" block or the `oats`, `oats-config` and
239
- `oats-packages` skills copied into its home; operational knowledge is the
240
- `oats.core` / `oats.setup` capabilities'. The `skills/oats-config` and
241
- `skills/oats-packages` directories are deleted.
242
- - **Session start, restart and capability commands on homes from an earlier
243
- kernel** (lead decision c3 Q2). A home whose `instance.json` records no
244
- `modules` answers `E_UNSUPPORTED_MODE` ("re-spawn it from the deployment").
245
- **`oats retire` still works on it**: no retire hook runs (the home records
246
- none), and the result's `warnings` says so.
247
- - **The conversion of a home that predates launch recipes** (lead decision
248
- c3c). `oats launch-config preview --home` still describes such a home as
249
- recorded (`selection.source: "frozen-command"`). Under a selection
250
- (`--runtime`, `--launch-config`, `--model`, `--yolo`/`--no-yolo`) it answers
251
- `E_LAUNCH_LEGACY` ("re-spawn it from the deployment; nothing was changed")
252
- instead of converting the recorded command.
253
- - **Classic `oats doctor`, schedule scope and team roots.** `oats doctor` is
254
- the workspace-model doctor only (`E_LOCAL_MISSING` with no deployment in
255
- reach; `--dir` is honoured). A schedule belongs to the deployment directory:
256
- with none in reach, `oats schedule` is `E_LOCAL_MISSING`, never an ambient
257
- `OATS_ROOT` / `PI_AGENTS_ROOT` scope. A deployment has one agents root; the
258
- cross-repository team roots (and `--parent` across them) are gone.
259
- - **The framework repository's root `oats-config.yaml`** and its only reader,
260
- `injects/framework-workspace.md`. The kernel refuses an `oats-config.yaml`
261
- between a command's directory and its deployment, so every instance whose
262
- work tree is a checkout of this repository failed every `oats` command; the
263
- root `oats-workspace.yaml` and `oats-membership.yaml` are the repository's
264
- config, and `scripts/validate-project.mjs` refuses a root `oats-config.yaml`.
265
- **Consequence:** a classic deployment rooted at a checkout of this repository
266
- (its root holds `agents/` and a 0.24/0.25 kernel reads the root
267
- `oats-config.yaml`) can spawn no new instance from that root once it pulls
268
- this change. Existing homes keep running and retire normally; the rebuild is
269
- `oats-local.yaml` + `oats onboard` on 0.26.0.
270
- - **The classic-era guides:** `docs/rebuild-to-v2.md` (the 0.24 → 0.25 rebuild
271
- guide) and its skill form, `oats.setup`'s `oats-rebuild`;
272
- `docs/operating-team-migration.md`; `docs/knowledge-migration.md` (OKF v1 →
273
- v2 for 0.23); `docs/workspace-adoption.md`; `docs/first-team-demo.md`;
274
- `docs/2026-09-03-architecture-proposal.md`. The catalog-pinned workspace
275
- example moved to [packages.md](../packages.md#declaring-packages-two-forms-in-one-place),
276
- where a test keeps its pins equal to `package-catalog.json`.
277
- - **`docs/oats-config.schema.json`**, the record of what 0.25 read.
278
- - **Kernel helpers of the v1 catalog migration:** `describeOfficialCatalog`
279
- (with its `oats install` acquire argv and approval notes) and
280
- `officialCapabilityPackage` (the `marketplace:` → package mapping);
281
- `officialCatalogFile` names the effective catalog file. `findRoot` no longer
282
- treats an `oats-config.yaml` without `agents/` as a package-only deployment
283
- root; a deployment without `agents/` gets `ensureRoot`'s `oats-local.yaml`
284
- remedy.
285
- - **The repository's root `log.md`** (the stale 0.24.2 working log).
286
- - **The "marketplace" name** for the official list: `docs/official-marketplace.md`
287
- is [official-catalog.md](../official-catalog.md), and the catalog's `policy`
288
- field points there.
56
+ `souls/<name>`. `oats create` is `E_UNKNOWN_COMMAND`, and `oats spawn
57
+ --instructions-file` / `--def-file` are `E_BAD_ARGS`, naming the
58
+ replacement (author the soul in a member repository, then `oats sync`).
59
+ `soul-scaffold` hooks no longer run. Capability-defined agents home at
60
+ `<deployment>/agents/<agent>/instances/<name>`; the agents root is the
61
+ closest `agents/` (or `PI_AGENTS_ROOT`).
62
+ - **Classic verbs.** `oats type`, `oats soul set` and `oats session recompose`
63
+ are `E_UNKNOWN_COMMAND` (edit the soul in its repository; re-spawn to
64
+ refresh). `oats status --team` is `E_BAD_ARGS`.
65
+ - **`oats-config.yaml` and the scope configuration chain.** One found between
66
+ a command's directory and its deployment is `E_CONFIG_BROKEN` (`reason:
67
+ "legacy-config"`); with no `oats-local.yaml` in reach, `E_LOCAL_MISSING`
68
+ names it. Where each key went:
69
+
70
+ | 0.25 key | 0.26.0 |
71
+ | --- | --- |
72
+ | `capabilities:`, `agent-types:` | `oats-workspace.yaml` `defaults:` and `soul.yaml`, then `oats sync` |
73
+ | `team:` | `oats-workspace.yaml` `teams:` and a soul's `team:` |
74
+ | `work-modes:` | a soul's `work:` and spawn flags; a worktree `setup:` script no longer runs |
75
+ | `yolo:` | `--yolo`, or a launch configuration's `yolo` |
76
+ | `launch-configs:` | `oats-local.yaml` (see Changed) |
77
+ | `agents-md-injection:`, `skill-overrides:`, `injection-override:` | removed; a duplicate skill is `E_SKILL_DUPLICATE` |
78
+
79
+ Hooks get the team facts `OATS_TEAM_SCOPE`, `OATS_TEAM_ID`,
80
+ `OATS_TEAM_LABEL`, `OATS_WORKSPACE_NAME` and `OATS_WORKSPACE_KEY`
81
+ (`OATS_TEAM_NAME` is always empty). A classic deployment rooted at a checkout
82
+ of the OATS repository can spawn nothing from that root once it pulls this
83
+ release (its root `oats-config.yaml` is gone); rebuild it with `oats
84
+ onboard`.
85
+ - **v1 soul fields** (`runtime`, `model`, `backend`, `repo`, `yolo`,
86
+ `launch-config`, `children`, `requires:`) are not read; use spawn flags,
87
+ launch configurations and `--allow-child-spawns` / `--no-child-spawns`.
88
+ - **Classic answers and scopes.** With no `oats-local.yaml` and no `--home`,
89
+ `oats inspect`, `readiness`, `operation run`, `doctor`, `spawn` and
90
+ `schedule` answer `E_LOCAL_MISSING` (`E_NO_DEPLOYMENT` now means only a
91
+ missing `agents/` root); an unreadable `--home` is `E_SESSION_UNKNOWN`.
92
+ `--verify-signatures` is always `E_BAD_ARGS`. A
93
+ deployment has one agents root; cross-repository team roots are gone.
94
+ - **Homes from an earlier kernel** (no `modules` in `instance.json`) answer
95
+ `E_UNSUPPORTED_MODE` to start, restart, `--home` reads and capability
96
+ commands; `oats retire` still works, runs no retire hook and says so. `oats
97
+ launch-config preview --home` under a selection answers `E_LAUNCH_LEGACY`.
98
+ - **Scheduling a capability agent by name.** A `kind: "spawn"` schedule names
99
+ a soul; schedule the capability's command (`kind: "command"`, for example
100
+ `oats okf harvest --soul <soul>`) or operation instead.
101
+ - **Leftovers:** the OAS scope probes, the installed tier, the v1 catalog
102
+ migration helpers, and the classic-era guides (including the 0.24 → 0.25
103
+ rebuild guide). The catalog-pinned workspace example is in
104
+ [packages.md](../packages.md#declaring-packages); the official list is the
105
+ [official catalog](../official-catalog.md), no longer "marketplace".
289
106
 
290
107
  ## Known limitations
291
108
 
292
109
  - **A scheduled wake's session start uses the spawn-time teams**
293
- (`OATS_TEAMS_SOURCE=recorded`), because the scheduler reads no remote. Its
294
- launch hook therefore leaves no team. The next operator
295
- `oats session start|restart`, or messaging command, is live.
296
-
297
- - **Joining teams beyond the personal one needs a later oats.aweb.** 0.26.0
298
- bundles and pins **oats.aweb 1.13.1**: every instance gets its primary aweb
299
- identity in the personal team (the aweb root's active team, or
300
- `settings.oats.aweb.team`; see teams amendment K under Changed), and the
301
- kernel hands the provider `OATS_TEAMS`, but 1.13.1 joins no further team.
302
- The team verbs (`messaging:teams|join|leave`, and `join=` at spawn) arrive
303
- with oats.aweb 1.14.x, pinned in a 0.26.x patch. There, joined teams **poll**
304
- (their mail is read between tasks); live receive for joined teams is planned
305
- for oats.aweb 1.15.
306
- - **A per-workspace personal team** (one personal team per person per
307
- workspace) needs aweb server support that is not yet deployed. Until then,
308
- "personal" is the person's active aweb team, shared across that person's
309
- workspaces.
110
+ (`OATS_TEAMS_SOURCE=recorded`), so its launch hook leaves no team. The next
111
+ operator start, restart or messaging command is live.
112
+ - **The bundled oats.aweb 1.13.1 joins no team beyond the personal one** (the
113
+ aweb root's active team, or `settings.oats.aweb.team`), though the kernel
114
+ hands it `OATS_TEAMS`.
115
+ - **"Personal" is the person's active aweb team,** shared across that
116
+ person's workspaces.
310
117
 
311
118
  ## Upgrading from 0.25
312
119
 
313
- - **Retire classic instances with 0.25, then onboard the deployment with
314
- 0.26.** A 0.25 deployment configured by `oats-config.yaml` is refused by
315
- 0.26.0 (`E_CONFIG_BROKEN` / `E_LOCAL_MISSING`, above). With the 0.25 kernel,
316
- retire its instances; then, with 0.26.0, write the deployment's
317
- `oats-local.yaml` (`oats onboard`), move what the old file declared into
318
- `oats-workspace.yaml` and each soul's `soul.yaml`, delete `oats-config.yaml`,
319
- and run `oats sync`. Homes left behind still retire under 0.26.0, but
320
- **no retire hook runs for them** (a pre-workspace home records no capability
321
- hooks): a messaging identity the 0.25 retire hook would have revoked stays
322
- live. Retire classic instances with the 0.25 kernel first, or revoke their
323
- identities by hand after retiring them with 0.26.0.
324
- - **Retire capability-agent instances before upgrading.** Instances homed
325
- under `<deployment>/local-agents/` (running knowledge harvesters, for
326
- example) are not managed by 0.26.0: it never reads, spawns into or retires
327
- from that directory, and only detects it (onboarding refuses into a
328
- directory that holds one). Retire them with the 0.25 kernel first, or accept that
329
- they are orphaned. While the directory exists, `oats status` and
330
- `oats doctor` report it once as the problem **`legacy-local-agents`** (JSON
331
- `problems[]`), naming the instances found there. Delete the directory once
332
- they are stopped.
333
-
334
- - **Wake needs aw 1.36.5 or later, and a daemon restart.** Scheduled and
335
- mail-driven wakes were verified end to end on aw 1.36.8 for session-delivery
336
- homes. After upgrading aw, restart the host's wake daemon so it re-registers.
337
-
338
- - **Captured homes and captured schedules** (from 0.24–0.25's captured path):
339
- retire each captured home — 0.26.0 retires it, but none of its captured
340
- retire hooks runs, so revoke the messaging identities and memberships named
341
- in the retire warnings with the provider's own tooling — and re-spawn the soul
342
- from the deployment. Remove each captured schedule job
343
- (`oats schedule remove --force <id>`) and re-add it without the captured keys.
120
+ - **Retire classic instances with 0.25, then onboard with 0.26.** With 0.26.0,
121
+ write `oats-local.yaml` (`oats onboard`), move what `oats-config.yaml`
122
+ declared into `oats-workspace.yaml` and each `soul.yaml`, delete it, and run
123
+ `oats sync`. Homes left behind retire under 0.26.0 with no retire hook, so
124
+ revoke their messaging identities by hand.
125
+ - **Retire instances under `local-agents/` first.** 0.26.0 does not manage
126
+ them; `oats status` and `oats doctor` report the problem
127
+ `legacy-local-agents` until the directory is deleted.
128
+ - **Wake needs aw 1.36.5 or later** (verified on 1.36.8), and a restart of the
129
+ host's wake daemon.
130
+ - **Captured homes and schedules:** retire each home, revoke the identities
131
+ its retire warnings name, and re-spawn the soul. Remove each captured
132
+ schedule (`oats schedule remove --force <id>`) and re-add it without the
133
+ captured keys.
344
134
 
345
135
  ## Added
346
136
 
347
- - **Private capabilities are listed as repo-owned** (human decision,
348
- 2026-09-25). `oats capabilities` (and `--json`) now lists a member
349
- capability whose manifest says `private: true`, with `private: true` on its
350
- row; the human table marks it "(repo-owned)". Enforcement is unchanged: only
351
- souls of its own repository can use it (`E_CAPABILITY_PRIVATE`). `oats sync`'s
352
- "· N private" count is of these capabilities. Feature
353
- `capabilities-private` in `oats version --json`; the Desktop shows its "Repo
354
- owned" section only when it is present.
355
- - **`oats spawn <soul> --name <slug>`** (human decision, 2026-09-24): an
356
- explicit, unprefixed instance name. The name is exactly `<slug>`, with no
357
- `<soul>-` prefix. Derived naming (`--purpose`, `<soul>-<n>`) stays the
358
- default.
359
- - `--name` and `--purpose` are mutually exclusive (`E_BAD_ARGS`).
360
- - The name is never rewritten: a non-slug, or a soul name of the deployment,
361
- is `E_INSTANCE_NAME_INVALID`.
362
- - A name that any soul of the deployment already holds, or that a live tmux
363
- window carries, is `E_INSTANCE_NAME_TAKEN`; never a silent `-2`.
364
- - `--preview` reports the final name and the same refusals, and
365
- `--expect-decision` binds the name.
366
- - Feature `spawn-name`.
367
- - **Instance names are at most 64 characters**, explicit and derived (the
368
- messaging alias allows 1–64). A longer name is `E_INSTANCE_NAME_INVALID` in
369
- preview and apply, and is never truncated. A derived name that would exceed
370
- 64 (a long purpose, or the `-2` suffix on a long one) is refused, naming the
371
- purpose to shorten. A spawn schedule whose run names
372
- (`<agent>-<purpose|id>-<YYYYMMDDHHMM>`) would exceed 64 is refused when it is
373
- saved (`E_SCHEDULE_INVALID`). Previously such a name passed the kernel and
374
- failed only at the messaging join.
375
- - **The retire summary names what a recovery copied and what it cost.** A
376
- workspace-model worktree has no disposable declaration, so its ignored build
377
- outputs (`node_modules/`, `build/` …) are copied to recovery with the
378
- uncommitted work: safe, not clean. A recovery (`workRecovery` /
379
- `workRecoveries[]` under `--json`, and its `recovery.json`) now carries
380
- `outputs: { paths: [{ path, bytes }], bytes }` (the untracked and ignored
381
- paths, or a directory's work entries, grouped by top-level entry, largest
382
- first) and its own `bytes`; the text summary prints the recovery's size and
383
- `copied outputs: node_modules/ (412.0 MiB), … — <total> in total`.
384
- - **`oats inspect --json` says where each layer's capability came from.**
385
- Each `layers.<layer>` row gains `from`: `"soul"`, `"workspace"` (a slot
386
- default or `defaults.capabilities`) or `"team:<label>"`
387
- (`defaults.byTeam.<label>`). It is `null` for an empty slot. A spawn records
388
- the rows in `instance.json` (`workspace.layers`), so `inspect --home`
389
- reports the spawn-time origin. A home spawned earlier reports `null`.
390
- Neither revision changes. Feature `layers-from`.
137
+ - **Private capabilities are listed as repo-owned** (`private: true` rows,
138
+ still usable only by their own repository's souls). Feature
139
+ `capabilities-private`.
140
+ - **`oats spawn <soul> --name <slug>`**: an explicit, unprefixed instance
141
+ name, never rewritten; exclusive with `--purpose`. Refusals:
142
+ `E_INSTANCE_NAME_INVALID`, `E_INSTANCE_NAME_TAKEN`. Feature `spawn-name`.
143
+ - **Instance names are at most 64 characters**, never truncated; a spawn
144
+ schedule whose run names would exceed 64 is refused when saved.
145
+ - **The retire summary names what a recovery copied** (`outputs`, `bytes`).
146
+ - **`oats inspect --json` says where each layer's capability came from**
147
+ (`layers.<layer>.from`: `soul`, `workspace` or `team:<label>`). Feature
148
+ `layers-from`.
391
149
 
392
150
  ## Changed
393
151
 
394
- - **Souls have no private mode** (human decision, 2026-09-25). `private:` in a
395
- `soul.yaml` is no longer honoured: every soul of a confirmed member, and
396
- every external soul, is listed (`oats souls`, `oats sync`) and spawnable, and
397
- a soul row's `private` is always `false`. The field is still accepted, so
398
- existing files validate (`docs/soul.schema.json` marks it deprecated), and
399
- each soul that carries it gets one **`soul-private-ignored`** warning in
400
- `oats sync` and `oats workspace status` (`warnings[]`: `{ code, soul,
401
- repoKey, path, message }`; "`private` has no effect on a soul since 0.26.0;
402
- remove it from souls/<name>/soul.yaml"). It is a warning, never a problem.
403
- - **Kernel: a capability whose `compatibility.oats` the running kernel doesn't
404
- satisfy is refused (`E_CAPABILITY_INCOMPATIBLE`).** This applies to package
405
- and member capabilities, and to capability agents, wherever a soul resolves
406
- (spawn, `spawn --preview`, `inspect --soul`, operator commands). The details
407
- name the capability, the range and the kernel. Before this, the workspace
408
- model never checked the range.
409
- - `oats inspect` capability rows carry `compatibility: { ok, range, kernel }`.
410
- - A home whose spawned module no longer admits the running kernel is not
411
- refused: `inspect --home` reports a `capability-incompatible` problem.
412
-
413
- - **Catalog: oats.authoring 1.0.3** (the bundled copy matches the tag byte for byte; the framework's `skills/integration-authoring` matches the package): the "core capabilities" wording.
414
- - **Catalog: oats.jira, oats.linear and oats.dev 1.0.1** (the bundled
415
- `capabilities/oats-{jira,linear,review}` copies match the tags byte for byte;
416
- the framework's copy of oats.review adds only `private: true`, a member-only
417
- key). Each now requires OATS >=0.26.0 and names only the workspace-model
418
- homes for its settings:
419
- - the soul's `tasks:` payload;
420
- - `settings.<cap>` in the deployment's `oats-local.yaml`;
421
- - `--provider` at spawn.
422
-
423
- oats.dev drops its `oats-config.yaml` config template and its package
424
- dependencies; oats.review is 1.2.1.
425
-
426
- - **A soul may name several team labels** (teams contract,
427
- [docs/design/2026-09-25-teams-contract.md](../design/2026-09-25-teams-contract.md)).
428
- The kernel passes each label's messaging payload to the provider as
429
- `OATS_TEAMS` (the eligible teams). Joining them is the messaging provider's
430
- job: oats.aweb 1.14.0 joins the default personal team only, and any other
431
- team on an explicit join.
432
- - `soul.yaml` `team` and `oats-membership.yaml`'s `team` take a label or a
433
- non-empty list of distinct labels; the first is the **primary**. A
434
- one-label soul composes exactly as before (same modules, skills, injects
435
- and `declRevision`); its messaging payload changes only by amendment K
436
- (below).
437
- - `defaults.byTeam[<label>].capabilities` applies for every label, in order.
438
- Two labels that give one capability different entries are
439
- `E_TEAM_CONFLICT` (naming both), unless the soul names that capability
440
- itself.
441
- - **The messaging provider no longer receives `byTeam[<label>]` merged into
442
- its settings** (teams amendment K, co-lead ruling), the primary's included:
443
- the settings are `base ⊕ soul ⊕ host ⊕ spawn`, and the per-label payloads
444
- are in `OATS_TEAMS`. `OATS_TEAM_ID` (the settings' `team`) is therefore the
445
- personal team a host, soul or spawn set; empty means the provider's
446
- default. With oats.aweb 1.13.1 the primary identity mints into the
447
- personal (root-active) team. The preview's `settingsOrigins` no longer
448
- shows a `workspace-team` origin.
449
- - **Revision change:** a soul whose primary label is mapped in
450
- `messaging.byTeam` gets a new `payloadRevision` and `revision` (its
451
- `declRevision` is unchanged), so a preview reports a payload change
452
- against instances spawned before this.
453
- - `OATS_TEAM_LABEL` stays the primary label. New: `OATS_TEAM_LABELS` (comma-joined), `OATS_TEAMS`
454
- (`[{ label, team, mapped, payload }]`, `[]` with no label) and
455
- `OATS_TEAMS_SOURCE` (`live` | `recorded`). All three are set in the
456
- environment of every hook, home command and provider check, and only
457
- there: a check's stdin request is unchanged, so providers that decode it
458
- strictly (oats.aweb 1.13.1) keep working. They are empty when a home's
459
- teams are unknown. A provider leaves a joined team only when the source is
460
- `live`.
461
- - A home's teams are **live** where they are acted on: the launch hook, the
462
- messaging module's commands and `messaging:` operations, and `inspect
463
- --home` read the workspace's current mappings in two repository reads (no
464
- discovery); `readiness --home` uses the discovery it already runs. Other
465
- capability commands and operations get the spawn-time list
466
- (`instance.json` `teams`, `recorded`) at no remote cost. The home's modules
467
- are unchanged.
468
- - `oats spawn --preview` and `oats inspect` show `teams`. A label with no
469
- `messaging.byTeam` entry is one `unmapped-team-label` warning, naming its
470
- souls, in `oats workspace status` / `oats sync`. Feature `teams`.
471
- - oats.aweb 1.13.1 ignores the new variables and keeps working.
472
-
473
- - **Declared setting keys.** The spawn preview's `modules[]` and `oats inspect`'s
474
- `capabilities[]` carry `declares`: the setting keys each manifest declares,
475
- sorted, names only (`[]` when none). Feature `settings-declared`.
476
-
477
- - **A home records its module skills.** `instance.json` `skills` lists each
478
- module skill as `{ name, source: "module:<capability>" }` beside the soul's
479
- own (`source: "soul"`), and `composition.materialized.skills` adds `from`:
480
- the home's module copy (`.oats/modules/<capability>/…`) the skill was copied
481
- from. Module skills sit under `.agents/skills/<capability>/<skill>/`.
482
- - **`oats launch-config list` with only a 0.25 `oats-config.yaml` in reach**
483
- answers `E_LOCAL_MISSING` naming the file instead of an empty list; inside a
484
- deployment the file is `E_CONFIG_BROKEN` with `details.reason:
485
- "legacy-config"`, as for every command.
486
- - **Launch configurations move to `oats-local.yaml`** (lead decision 2: a
487
- spawn-time host choice). The deployment's `oats-local.yaml` gains a
488
- `launch-configs:` key with the same entries (`runtime`, `executable`, `args`,
489
- `env`, `model`, `yolo`); `oats launch-config set | remove` rewrite only that
490
- block, and `list` / `preview`, `--launch-config` on `oats spawn` and on
491
- `oats session start | restart`, and the `launch-config` feature are unchanged.
492
- There is one host file and no scope chain: `list` rows keep `source` (the
493
- deployment directory) and an always-empty `shadows`. A relative `executable`
494
- resolves against the deployment directory. A home's launch configurations
495
- are its deployment's, found walking up from the home.
496
- - **Upgrading:** a scope's `oats-config.yaml` that still declares
497
- `launch-configs:` is refused (its readers, and the `launch-config`
498
- commands, name the move). Move the block into `oats-local.yaml`, or
499
- re-declare each entry with `oats launch-config set <name> --file <json>`
500
- from the deployment. `set` with no `oats-local.yaml` in reach is
501
- `E_LOCAL_MISSING`.
502
- - **The capability manifest contract is checked where a workspace reads the
503
- manifest.** The rules the kernel enforced only on classic capabilities now
504
- apply to member and package capabilities too, before anything runs:
505
- - a launch `environment` name inside the capability's vendor namespace (or an
506
- `environmentNamespaces` prefix that is not reserved), never a core or
507
- process bootstrap variable;
508
- - hooks: an approved event, a command string or `{ command, required,
509
- inputs }`, `required: true` only on the spawn hook, and a script path inside
510
- the capability directory;
511
- - hooks and launch environment only on a dotted id (`acme.tool`): an
512
- undotted id has no vendor namespace to claim.
513
-
514
- A member capability that breaks one is a discovery problem
515
- (`E_WORKSPACE_SCHEMA` at `capabilities/<dir>/oats.json#<pointer>`, shown by
516
- `oats workspace status`) and is not listed; a soul that declares it is
517
- refused with that problem (`reason: "manifest-contract"`), not "missing". A
518
- package capability that breaks one is `E_PACKAGE_MANIFEST` at `oats sync`.
519
- - **A provider payload value outside the manifest's `settings.<key>.values`
520
- is refused** (`E_WORKSPACE_SCHEMA`, `reason: "setting-value"`, naming where
521
- it was set: a `--provider` flag, `oats-local.yaml` settings, the soul or the
522
- workspace). A misspelled value used to be recorded and skip every
523
- conditional `requires` row that reads it.
524
- - **A capability agent is a workspace-model spawn of its providing module
525
- only** (lead decision c3 Q1). `oats spawn <agent>` for a capability's
526
- `agents:` soul (OKF's `memory-harvest`, `oats.review`'s `reviewer`) records
527
- `modules`/`providers`/`workspace` like any v2 home, and composes exactly one
528
- module: the capability that declares the agent. The module comes from the
529
- `--parent`/`--relative-to` instance's verified copy (pinned to its recorded
530
- digest, with its recorded payload), else from a home that carries it, else
531
- from a confirmed member capability or a locked package that declares the
532
- agent (the source instance may be gone). A capability agent gets no
533
- knowledge, messaging or tasks module and runs no provider hook, its providing
534
- module's included: a harvester never registers as a knowledge source or gets
535
- a messaging identity. A knowledge-layer provider's inject is left out.
536
- - **`instance.json` records `workspace.name` and `workspace.deployment`**
537
- (M5/3a). `oats inspect --home` reports the recorded workspace name without
538
- discovery, and `oats operation run --home` hands it to the provider as
539
- `OATS_WORKSPACE_NAME`. Homes spawned before 0.26.0 have neither.
540
-
152
+ - **Souls have no private mode.** `private:` in `soul.yaml` is accepted but
153
+ ignored, with a `soul-private-ignored` warning.
154
+ - **A capability whose `compatibility.oats` the kernel does not satisfy is
155
+ refused** (`E_CAPABILITY_INCOMPATIBLE`); an existing home reports
156
+ `capability-incompatible` instead.
157
+ - **Catalog:** oats.authoring 1.0.3; oats.jira, oats.linear and oats.dev
158
+ 1.0.1 (require OATS >=0.26.0, settings only from the workspace model);
159
+ oats.review 1.2.1.
160
+ - **A soul may name several team labels**; the first is the primary. Each
161
+ label's `defaults.byTeam` applies (`E_TEAM_CONFLICT` on a clash). The
162
+ messaging provider's settings no longer merge `byTeam[<label>]`; the
163
+ per-label payloads travel in `OATS_TEAMS`, beside `OATS_TEAM_LABELS` and
164
+ `OATS_TEAMS_SOURCE`, and a soul whose primary label is mapped gets a new
165
+ `payloadRevision`. Feature `teams`. See the
166
+ [teams contract](https://github.com/awebai/oats/blob/7838d3ca70772f63854b198601fbc45437c2e999/docs/design/2026-09-25-teams-contract.md).
167
+ - **Launch configurations move to `oats-local.yaml`** (`launch-configs:`).
168
+ Move the block, or re-declare each entry with `oats launch-config set`. See
169
+ [configuration.md](../configuration.md#launch-configurations).
170
+ - **The capability manifest contract applies to member and package
171
+ capabilities** (`E_WORKSPACE_SCHEMA` / `E_PACKAGE_MANIFEST`), and a payload
172
+ value outside `settings.<key>.values` is refused.
173
+ - **A capability agent composes only its providing module**, with no
174
+ knowledge, messaging or tasks module.
541
175
  - **`oats inspect`, `oats readiness` and `oats operation run` read the
542
- workspace model** on a workspace deployment and for every home whose
543
- `instance.json` records `modules`. They never read the classic config chain.
544
- The probe integers are the gate: `operationsApi: 2`, `soulsApi: 2` (the
545
- inspect soul rows) and `readinessApi: 2`. `oats souls --json` keeps
546
- `soulsApi: 1`, since its shape is unchanged. Shapes and examples are in
176
+ workspace model** (`operationsApi: 2`, `soulsApi: 2`, `readinessApi: 2`).
177
+ Readiness checks are `installed | configured | member | providers`. See
547
178
  [desktop-cli-api.md](../desktop-cli-api.md#inspect-readiness-and-operation-run-on-the-workspace-model-operationsapi-2-soulsapi-2-readinessapi-2-oats-0260).
548
- - The subject is an instance (`--home`: `{kind:"instance", instance, home,
549
- soul}`) or a soul (`--soul`: `{kind:"soul", soul, repoKey, commit,
550
- team}`). A workspace deployment with neither is `E_BAD_ARGS`; the
551
- scope-wide lists are `oats souls` and `oats capabilities`.
552
- - Payloads lose `scope` (`chain`, `team`, `agentsRoots`), config `levels`,
553
- `activation`, `currentConfig`, `snapshot`, `health.trusted` and the
554
- portable `sources`. A capability's origin is its module's `from`; its
555
- settings are the merged provider payload.
556
- - Readiness checks are `installed | configured | member | providers`:
557
- - `trusted` is removed, and `--verify-signatures` is `E_BAD_ARGS`.
558
- - `enrolled` is now `member`: the soul's member repository confirmed in
559
- the workspace (`oats-membership.yaml`), never `oats.yaml`.
560
- - `providers` is new: each bound provider's own binding check, relayed
561
- verbatim as `{status, problems, warnings}`. The status maps to the item:
562
- - `ready` → pass;
563
- - `needs-configuration` or `authorization-required` → fail;
564
- - `unavailable` → unknown.
565
-
566
- `warnings` is optional in the provider's answer and always present in
567
- the relay (`[]` when absent). It never changes the status: a ready
568
- binding with a warning still passes. The answer is decoded by the
569
- binding wire's rules (exit 0, one strict JSON document, the envelope
570
- echo, no problems on `ready`); anything else is `unknown`. All provider
571
- checks share one 60 s budget per read. Provider authors: the request,
572
- environment and answer are specified in
573
- [capabilities.md](../capabilities.md#readiness-check-bindingcheck).
574
- - A soul whose packages the lock does not provide fails `installed` with
575
- the typed code and an `oats sync` remedy.
576
- - The probe's integers say the kernel can answer the v2 shapes. Dispatch
577
- on each payload's own integer; the v1 shapes are removed (see Removed).
578
- - The `readiness-verify` feature is no longer advertised.
579
- - A v2 home's deployment is derived from its path
580
- (`<deployment>/agents/<soul>/instances/<name>`), and
581
- `<deployment>/oats-local.yaml` must exist exactly there (`E_HOME_MISMATCH`
582
- otherwise). A v2 spawn ignores an ambient `PI_AGENTS_ROOT` / `OATS_ROOT`.
583
- - A module tree in the deployment's store (used by readiness `--soul`,
584
- `operation run --soul` and `oats <ns>` dispatch) runs only while it
585
- matches the digest verified when it was fetched at the locked commit. A
586
- drifted tree is fetched again; a fetch that does not verify is
587
- `E_PACKAGE_INTEGRITY`.
588
- - `readiness --policy` is kept, with the same shape. The selector echo moves
589
- from `subject.selector` to a top-level `selector`.
590
- - `oats operation run` runs the module that fills the layer for the home or
591
- the soul. There is no trust gate, and the result carries
592
- `operationsApi: 2`. Remote routing accepts a destination advertising
593
- `operationsApi` 1 or 2.
594
-
595
- - **Manifest setting defaults reach workspace spawns** (addendum 5). A
596
- capability's declared `settings.<key>.default` (for example oats.aweb's
597
- `identity: { mode: local }`) is now the lowest layer of the merged provider
598
- payload on `oats spawn`, `--preview` and `oats inspect --soul`, below the
599
- workspace, team, soul, host and `--provider` layers. The provider receives it
600
- in `OATS_SETTINGS` and `instance.json` `providers.<cap>` records it. The
601
- preview's new `settingsOrigins.<cap>` says where each leaf came from
602
- (`manifest-default`, `workspace`, `workspace-team`, `soul`, `host`,
603
- `spawn`; feature `settings-origins`), so a Desktop shows "Default" without
604
- hardcoding it. The decision
605
- binds the payload by value, defaults included. An instance spawned before
606
- 0.26.0 keeps the payload it recorded, without the defaults.
179
+ - **Manifest setting defaults reach workspace spawns** as the lowest payload
180
+ layer; the preview's `settingsOrigins` says where each value came from
181
+ (feature `settings-origins`).
182
+ - Spawn previews and `oats inspect` report each module's declared setting keys
183
+ (feature `settings-declared`); `instance.json` records module skills and
184
+ `workspace.name` / `workspace.deployment`.
607
185
 
608
186
  ## Fixed
609
187
 
610
- - **Every team label's messaging payload is validated.** A soul with several
611
- labels had only its primary label's `messaging.byTeam` entry checked, though
612
- every label's entry reaches the provider in `OATS_TEAMS`. A secondary
613
- label's entry could carry a manifest `hostOnly` key or a nested `byTeam`
614
- unchecked. Each label the soul carries is now refused the same way, with
615
- `E_WORKSPACE_SCHEMA` (reason `host-only-key` or `reserved-key`) and the
616
- path `/messaging/byTeam/<label>/…`.
617
- - **Team facts in a home's launch and retire hooks.** A home's `launch` and
618
- `retire` hooks received an empty `OATS_TEAM_LABEL` and `OATS_TEAM_ID`. The
619
- kernel read the recorded workspace in the wrong shape, while spawn hooks and
620
- home commands got the right values. They now get the soul's primary label and
621
- the recorded messaging payload's team id.
622
- - **Session start and restart of a workspace-model home.** Every start or
623
- restart of a home that records `modules` and a launch recipe refused with
624
- `E_LAUNCH_PREPARATION` ("… is no longer installed in the scope"): the
625
- launch providers' manifests were looked up from the home's recorded work
626
- repository instead of the home's own module copies. A module home now reads
627
- them from `<home>/.oats/modules`, and is never re-resolved against the scope;
628
- a module copy that is missing is its own refusal naming the directory.
629
-
630
- - **A spawn preview writes nothing, the first one included.** The first
631
- `oats spawn <soul> --preview` of a workspace soul (or of a new member commit)
632
- used to fill the deployment's soul cache (`agents/<soul>/souls/<commit>/`)
633
- and move the `agents/<soul>/soul` pointer. A preview now reads the cache when
634
- a spawn already filled it, else fetches the soul to a temporary copy outside
635
- the deployment and removes it; `soulFetched: true` still says it fetched. The
636
- deployment is byte-identical after any preview, as `spawnPreviewApi 2`
637
- promises (docs/desktop-cli-api.md).
638
-
639
- - **`oats retire <unknown>` is a typed refusal.** An instance name with no home
640
- under the agents root used to escape as an untyped error with a stack trace
641
- (no `--json` envelope). It is now `E_SESSION_UNKNOWN` (`no instance named
642
- "<name>"`), the code every lookup by instance name answers, exit 1, one
643
- envelope under `--json`.
644
-
645
- - **Instance names are unique across the deployment.** A derived name used to
646
- de-duplicate only within its own soul's `instances/`, so soul `a` with
647
- `--purpose b-c` and soul `a-b` with `--purpose c` both got `a-b-c`. Derived
648
- names now skip every instance and soul name in the deployment (`-2`, `-3`, …).
649
-
650
- - **`oats status` shows a workspace soul as it is written.** A soul row read a
651
- `schemaVersion: 2` soul.yaml with the classic flat reader: a nested map
652
- (`capabilities`, `knowledge` …) came out as `""` and `schemaVersion` as the
653
- string `"2"`. Such a soul.yaml is now read with the YAML parser: the row
654
- carries the maps as maps, `schemaVersion: 2` and booleans as booleans.
655
-
656
- - **`oats doctor --soul <name>` includes module injects.** On a workspace
657
- deployment it composed through the classic config chain, so the capability
658
- injects a spawned home carries were missing. It now resolves the soul over
659
- the workspace remotes as a spawn preview does and composes the full text
660
- (module inject blocks are named home-relative, `.oats/modules/<cap>/…`). It
661
- writes nothing in the deployment; an unknown soul is `E_SOUL_UNKNOWN`.
662
- Without `--soul`, doctor stays offline.
663
-
664
- - **Capability commands recognise `OATS_INSTANCE_HOME`.** Dispatch found the
665
- instance home only from `PI_AGENT_HOME` / `OATS_HOME`; the canonical
666
- `OATS_INSTANCE_HOME` now counts, and wins when several are set.
667
-
668
- - **Launch-preparation refusals name no removed verb.** The classic
669
- `E_LAUNCH_PREPARATION` remedies said "reinstall it (oats install)" and
670
- "re-trust it (oats trust)"; the remedy is now "respawn the instance".
188
+ - Every team label's messaging payload is validated, not only the primary's.
189
+ - Launch and retire hooks get the primary `OATS_TEAM_LABEL` and
190
+ `OATS_TEAM_ID` (they were empty).
191
+ - Session start and restart of a workspace-model home no longer refuse with
192
+ `E_LAUNCH_PREPARATION`.
193
+ - A spawn preview writes nothing to the deployment, the first one included.
194
+ - `oats retire <unknown>` is `E_SESSION_UNKNOWN`.
195
+ - Derived instance names are unique across the deployment.
196
+ - `oats status` reads a `schemaVersion: 2` soul.yaml correctly.
197
+ - `oats doctor --soul <name>` includes module injects.
198
+ - Capability commands recognise `OATS_INSTANCE_HOME`.
199
+ - `E_LAUNCH_PREPARATION` remedies no longer name removed verbs.