@awebai/oats 0.25.9 → 0.27.0

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 (183) hide show
  1. package/README.md +8 -6
  2. package/bin/oats.mjs +648 -1755
  3. package/capabilities/oats-authoring/oats-package.json +2 -2
  4. package/capabilities/oats-authoring/oats.json +2 -2
  5. package/capabilities/oats-authoring/skills/integration-authoring/SKILL.md +46 -25
  6. package/capabilities/oats-authoring/skills/soul-craft/SKILL.md +13 -6
  7. package/capabilities/oats-aweb/bin/oats-aweb.mjs +279 -93
  8. package/capabilities/oats-aweb/injects/aweb.md +7 -2
  9. package/capabilities/oats-aweb/lib/binding-wire.mjs +89 -13
  10. package/capabilities/oats-aweb/lib/captured-native.mjs +1 -1
  11. package/capabilities/oats-aweb/lib/grant-custody.mjs +38 -0
  12. package/capabilities/oats-aweb/oats.json +8 -4
  13. package/capabilities/oats-jira/bin/oats-jira.mjs +4 -4
  14. package/capabilities/oats-jira/oats.json +2 -2
  15. package/capabilities/oats-jira/skills/jira-tasks/SKILL.md +6 -3
  16. package/capabilities/oats-linear/bin/oats-linear-hook.mjs +6 -4
  17. package/capabilities/oats-linear/oats.json +2 -2
  18. package/capabilities/oats-linear/skills/linear-tasks/SKILL.md +6 -0
  19. package/capabilities/oats-review/oats.json +3 -2
  20. package/docs/capabilities.md +229 -58
  21. package/docs/capability-manifest.schema.json +29 -9
  22. package/docs/configuration.md +17 -5
  23. package/docs/conventions.md +18 -28
  24. package/docs/design/2026-09-08-expert-assisted-deployment-proposal.md +1 -1
  25. package/docs/design/2026-09-13-knowledge-and-memory-direction.md +3 -3
  26. package/docs/design/2026-09-14-portable-souls-and-git-workspaces.md +2 -2
  27. package/docs/design/2026-09-15-portable-souls-handoff.md +2 -2
  28. package/docs/design/2026-09-15-portable-souls-implementation.md +1 -1
  29. package/docs/design/2026-09-20-redesign-program-board.md +2 -2
  30. package/docs/design/2026-09-23-workspace-module-contracts.md +1 -1
  31. package/docs/design/2026-09-23-workspace-v2-implementation-plan.md +1 -1
  32. package/docs/design/2026-09-24-desktop-phase-f-boundary.md +34 -1
  33. package/docs/design/2026-09-24-phase-d-plan.md +57 -0
  34. package/docs/design/2026-09-25-teams-contract.md +226 -0
  35. package/docs/design/README.md +3 -3
  36. package/docs/design/launch-configurations.md +20 -16
  37. package/docs/design/operations-contract.md +27 -10
  38. package/docs/desktop-cli-api.md +604 -271
  39. package/docs/desktop-instance-start.md +3 -3
  40. package/docs/desktop.md +7 -13
  41. package/docs/execution-targets.md +16 -18
  42. package/docs/first-team.md +15 -18
  43. package/docs/implementation.md +31 -62
  44. package/docs/integrations.md +64 -33
  45. package/docs/knowledge-capability-authoring.md +1 -1
  46. package/docs/knowledge-reference/package-craft.md +10 -8
  47. package/docs/knowledge-theory.md +1 -1
  48. package/docs/knowledge.md +10 -11
  49. package/docs/layers.md +16 -17
  50. package/docs/oats-local.schema.json +30 -1
  51. package/docs/oats-membership.schema.json +5 -3
  52. package/docs/oats-package.schema.json +2 -2
  53. package/docs/oats-workspace.schema.json +1 -1
  54. package/docs/{official-marketplace.md → official-catalog.md} +15 -16
  55. package/docs/packages.md +76 -53
  56. package/docs/release-notes/v0.22.0.md +1 -1
  57. package/docs/release-notes/v0.23.1.md +1 -1
  58. package/docs/release-notes/v0.26.0.md +670 -0
  59. package/docs/release-notes/v0.27.0.md +100 -0
  60. package/docs/schedules.md +54 -132
  61. package/docs/servers.md +4 -4
  62. package/docs/soul.schema.json +11 -4
  63. package/docs/souls-and-instances.md +60 -47
  64. package/docs/workspaces.md +80 -58
  65. package/injects/instance-boundary.md +2 -2
  66. package/injects/work-attached.md +1 -1
  67. package/injects/work-workspace.md +2 -2
  68. package/lib/{portable-files.mjs → bounded-read.mjs} +6 -6
  69. package/lib/{portable-values.mjs → canonical-json.mjs} +3 -12
  70. package/lib/capability-contract.mjs +110 -0
  71. package/lib/config-data.mjs +2 -2
  72. package/lib/core.mjs +947 -5023
  73. package/lib/deprecation.mjs +24 -0
  74. package/lib/digest.mjs +12 -0
  75. package/lib/instance-inspect.mjs +397 -0
  76. package/lib/instance-lifecycle.mjs +3 -4
  77. package/lib/instance-resolution.mjs +212 -26
  78. package/lib/instruction-composition.mjs +0 -20
  79. package/lib/materialize.mjs +6 -4
  80. package/lib/operator-dispatch.mjs +33 -13
  81. package/lib/packages.mjs +25 -190
  82. package/lib/process-group.mjs +1 -1
  83. package/lib/provider-binding.mjs +4 -2
  84. package/lib/provider-reasons.mjs +3 -68
  85. package/lib/remote.mjs +1 -1
  86. package/lib/resolve.mjs +204 -68
  87. package/lib/schedule.mjs +136 -292
  88. package/lib/servers.mjs +70 -38
  89. package/lib/{portable-shape.mjs → shape.mjs} +4 -3
  90. package/lib/tree-copy.mjs +44 -0
  91. package/lib/workspace.mjs +132 -20
  92. package/package-catalog.json +6 -6
  93. package/package.json +1 -1
  94. package/packages/record/lib/session-roots.mjs +8 -6
  95. package/skills/integration-authoring/SKILL.md +48 -40
  96. package/skills/oats-getting-started/SKILL.md +105 -110
  97. package/skills/oats-support/SKILL.md +2 -2
  98. package/skills/soul-craft/SKILL.md +13 -6
  99. package/bin/oats-pi-sdk-host.mjs +0 -17
  100. package/docs/2026-09-03-architecture-proposal.md +0 -642
  101. package/docs/artifact-approvals.schema.json +0 -7
  102. package/docs/captured-invocation-context.schema.json +0 -7
  103. package/docs/captured-resolution.schema.json +0 -7
  104. package/docs/design/package-engine-contract.md +0 -813
  105. package/docs/design/package-runtime-api.md +0 -588
  106. package/docs/desktop-succession.md +0 -57
  107. package/docs/execution-capsule.schema.json +0 -108
  108. package/docs/first-team-demo.md +0 -92
  109. package/docs/knowledge-migration.md +0 -147
  110. package/docs/migration-from-oas.md +0 -103
  111. package/docs/oats-config.schema.json +0 -172
  112. package/docs/oats-lock-v3.schema.json +0 -7
  113. package/docs/oats-lock.schema.json +0 -175
  114. package/docs/operating-team-migration.md +0 -470
  115. package/docs/portable.schema.json +0 -2512
  116. package/docs/provider-check-input.schema.json +0 -7
  117. package/docs/rebuild-to-v2.md +0 -511
  118. package/docs/workspace-adoption.md +0 -74
  119. package/injects/framework-workspace.md +0 -7
  120. package/injects/local-soul.md +0 -19
  121. package/injects/oats-portable.md +0 -20
  122. package/injects/oats.md +0 -11
  123. package/injects/portable-instance-boundary.md +0 -39
  124. package/injects/portable-work-directory.md +0 -29
  125. package/lib/artifact-approvals.mjs +0 -120
  126. package/lib/artifact-tree.mjs +0 -141
  127. package/lib/capability-artifacts.mjs +0 -179
  128. package/lib/capability-execution.mjs +0 -15
  129. package/lib/capability-inputs.mjs +0 -39
  130. package/lib/capability-provenance.mjs +0 -231
  131. package/lib/captured-action-shape.mjs +0 -21
  132. package/lib/captured-admission-shape.mjs +0 -20
  133. package/lib/captured-binding-file.mjs +0 -36
  134. package/lib/captured-dispatch.mjs +0 -66
  135. package/lib/captured-instance-index.mjs +0 -277
  136. package/lib/captured-invocation-context.mjs +0 -130
  137. package/lib/captured-launch-request.mjs +0 -66
  138. package/lib/captured-operation-process.mjs +0 -15
  139. package/lib/captured-pi-custody.mjs +0 -29
  140. package/lib/captured-pi-host.mjs +0 -167
  141. package/lib/captured-pi-outcome.mjs +0 -172
  142. package/lib/captured-resolutions.mjs +0 -275
  143. package/lib/captured-scaffold.mjs +0 -87
  144. package/lib/captured-selector.mjs +0 -28
  145. package/lib/captured-session-backend.mjs +0 -52
  146. package/lib/captured-source-receipt-file.mjs +0 -72
  147. package/lib/helper-injection-policy.mjs +0 -104
  148. package/lib/legacy-lock-codec.mjs +0 -106
  149. package/lib/manifest-settings.mjs +0 -84
  150. package/lib/package-closure.mjs +0 -48
  151. package/lib/package-materialization.mjs +0 -83
  152. package/lib/pi-sdk-host.mjs +0 -229
  153. package/lib/portable-artifacts.mjs +0 -115
  154. package/lib/portable-choices.mjs +0 -82
  155. package/lib/portable-composition.mjs +0 -136
  156. package/lib/portable-digest.mjs +0 -105
  157. package/lib/portable-identity.mjs +0 -40
  158. package/lib/portable-lock.mjs +0 -117
  159. package/lib/portable-onboarding-request.mjs +0 -49
  160. package/lib/portable-onboarding.mjs +0 -256
  161. package/lib/portable-package-preparation.mjs +0 -188
  162. package/lib/portable-policy.mjs +0 -44
  163. package/lib/portable-soul.mjs +0 -42
  164. package/lib/portable-state.mjs +0 -80
  165. package/lib/prepare-composition.mjs +0 -170
  166. package/lib/prepared-bindings.mjs +0 -92
  167. package/lib/prepared-resources.mjs +0 -127
  168. package/lib/provider-binding-broker.mjs +0 -65
  169. package/lib/provider-binding-wire.mjs +0 -116
  170. package/lib/readiness.mjs +0 -225
  171. package/lib/repository-observation.mjs +0 -226
  172. package/lib/resolution-shape.mjs +0 -393
  173. package/lib/schedule-capsule.mjs +0 -206
  174. package/lib/soul-constraints.mjs +0 -40
  175. package/lib/source-projection.mjs +0 -84
  176. package/lib/source-spec.mjs +0 -189
  177. package/lib/workspace-definition.mjs +0 -126
  178. package/lib/workspace-discovery.mjs +0 -146
  179. package/skills/oats/SKILL.md +0 -162
  180. package/skills/oats-config/SKILL.md +0 -164
  181. package/skills/oats-packages/SKILL.md +0 -184
  182. package/skills/oats-portable/SKILL.md +0 -115
  183. package/skills/oats-portable-artifacts/SKILL.md +0 -63
@@ -6,8 +6,8 @@ instance-local views for deployment composition.
6
6
  ## Operating documents
7
7
 
8
8
  ```text
9
- soul/AGENTS.md # canonical role instructions
10
- soul/CLAUDE.md -> AGENTS.md
9
+ souls/<name>/AGENTS.md # canonical role instructions (in the member repo)
10
+ souls/<name>/CLAUDE.md -> AGENTS.md
11
11
  instance/AGENTS.md # generated regular file
12
12
  instance/CLAUDE.md -> AGENTS.md
13
13
  ```
@@ -48,8 +48,8 @@ Pi with ambient skill and context discovery disabled and the one instance path
48
48
  explicit; that exclusion is gone.)* Claude runs provider-native: it reads the
49
49
  instance's `.claude/skills` and `CLAUDE.md` symlinks, and the operator's own
50
50
  user and project configuration — skills, plugins, settings — stays in effect.
51
- Neither runtime gets a redirected config home.
52
- `composition.materialized.runtimePosture` in `instance.json` records what each
51
+ Neither harness gets a redirected config home.
52
+ `composition.materialized.harnessPosture` in `instance.json` records what each
53
53
  instance actually exposes. `oats-getting-started` is the sole pre-workspace
54
54
  ambient bootstrap.
55
55
 
@@ -66,35 +66,25 @@ where its owner keeps it and is copied whole into each instance at spawn:
66
66
  ```text
67
67
  <member repo>/capabilities/<name>/oats.json # member-tier capability, latest state (membership is the trust)
68
68
  <package repo>/oats-package/oats-package.json # package-tier: versioned via oats-workspace.yaml packages:
69
- <deployment>/oats-lock.json # lockfileVersion 3: package commit, integrity, per-version approval
69
+ <deployment>/oats-lock.json # lockfileVersion 3: package commit and integrity
70
70
  <instance>/.oats/modules/<capability>/ # the copy this instance runs
71
71
  ```
72
72
 
73
- **Classic 0.24 layout** (still launched by the 0.24 kernel; a 0.25 kernel
74
- reads none of it as configuration — see [rebuild-to-v2.md](rebuild-to-v2.md)):
75
-
76
- ```text
77
- <package>/capabilities/<name>/oats.json # the official marketplace (install source, not ambient)
78
- <level>/.agents/capabilities/installed/<name>/oats.json # acquired (gitignored, restorable)
79
- <level>/.agents/capabilities/owned/<name>/oats.json # authored at this scope (source; committed where the scope is a repo)
80
- <level>/oats-lock.json # lockfileVersion 2: external source/integrity/trust
81
- ```
82
-
83
73
  ## Quick map
84
74
 
85
- | Thing | Canonical location (0.25 workspace model) | 0.24 classic |
86
- |---|---|---|
87
- | Shared declaration | `oats-workspace.yaml` in the host repo; `oats-membership.yaml` in every member | `oats-config.yaml` chain, `oats.yaml` |
88
- | Per-machine config | `<deployment>/oats-local.yaml` (uncommitted) | `oats-config.yaml` `settings:` |
89
- | Acquisition lock | `<deployment>/oats-lock.json` (v3) | `<level>/oats-lock.json` (v2) |
90
- | Soul source | `<member repo>/souls/<name>/` | `agents/<name>/soul/` |
91
- | Soul operating doc | `souls/<name>/AGENTS.md` | `soul/AGENTS.md` |
92
- | Soul Claude view | `souls/<name>/CLAUDE.md -> AGENTS.md` | `soul/CLAUDE.md -> AGENTS.md` |
93
- | Soul-private skills | `souls/<name>/skills/` | `soul/skills/` |
94
- | Instance operating doc | `instance/AGENTS.md` (generated) | same |
95
- | Instance skill set | `instance/.agents/skills/` | same |
96
- | Instance modules | `instance/.oats/modules/<capability>/` | `.agents/capabilities/installed/` (shared) |
97
- | Instance metadata | `instance/instance.json` (`modules{}`, `providers{}`, `workspace{}`) | `instance/instance.json` |
75
+ | Thing | Canonical location |
76
+ |---|---|
77
+ | Shared declaration | `oats-workspace.yaml` in the host repo; `oats-membership.yaml` in every member |
78
+ | Per-machine config | `<deployment>/oats-local.yaml` (uncommitted) |
79
+ | Acquisition lock | `<deployment>/oats-lock.json` (v3) |
80
+ | Soul source | `<member repo>/souls/<name>/` |
81
+ | Soul operating doc | `souls/<name>/AGENTS.md` |
82
+ | Soul Claude view | `souls/<name>/CLAUDE.md -> AGENTS.md` |
83
+ | Soul-private skills | `souls/<name>/skills/` |
84
+ | Instance operating doc | `instance/AGENTS.md` (generated) |
85
+ | Instance skill set | `instance/.agents/skills/` |
86
+ | Instance modules | `instance/.oats/modules/<capability>/` |
87
+ | Instance metadata | `instance/instance.json` (`modules{}`, `providers{}`, `workspace{}`) |
98
88
 
99
89
  Symlinks prevent compatibility paths from drifting. Generated regular files
100
90
  separate canonical portable identity from scope-dependent runtime policy.
@@ -32,7 +32,7 @@ how to choose and combine them. A working installation must remain operable
32
32
  without the expert running or the original setup conversation being available.
33
33
 
34
34
  The architecture principle is already in the
35
- [September 3 proposal](../2026-09-03-architecture-proposal.md):
35
+ September 3 architecture proposal (removed in 0.26.0; it is in the v0.25.x tags):
36
36
 
37
37
  > Contracts and bootstrap skills in OATS; implementations in packages.
38
38
 
@@ -85,8 +85,8 @@ code already says**.
85
85
  ## 2. Vocabulary
86
86
 
87
87
  These terms are used precisely throughout. Most are already OATS vocabulary
88
- (`docs/knowledge.md`, `docs/knowledge-theory.md`,
89
- `docs/2026-09-03-architecture-proposal.md`); the new ones are marked.
88
+ (`docs/knowledge.md`, `docs/knowledge-theory.md`, the September 3
89
+ architecture proposal); the new ones are marked.
90
90
 
91
91
  | Term | Meaning |
92
92
  |---|---|
@@ -721,7 +721,7 @@ repository is named.
721
721
  | 2026-07-26 | Provider-agnostic specialization: compounding expertise across sessions, models, and runtimes; memory outside any one harness. | `decisions/provider-agnostic-specialization-and-curated-context.md`. |
722
722
  | 2026-08-27 | Investigation of the public auto-memory audit: governed memory must survive that audit; developer souls must not mirror code; harness-agnostic knowledge enables mixed-runtime teams. | `lessons/governed-memory-survives-auto-memory-audit.md`, `lessons/developer-souls-should-not-mirror-code.md`, `lessons/harness-agnostic-knowledge-enables-mixed-runtime-teams.md`; the video "Turn off Claude Code's Memory" (Theo, t3.gg, YouTube id Jf54k7tFeEc). |
723
723
  | 2026-08-27 | Founder correction: developer and UX souls hold decisions, rejected alternatives, inspiration genealogy, and typed slow state; the bias is against descriptions, not decisions. Decision-vs-description; one home per decision; freshness discipline. | Steward note `decision-vs-description-and-knowledge-homing.md` (instance notes, pending harvest); relayed to the OATS coordinator on 2026-09-04. |
724
- | 2026-09-03/04 | OATS architecture proposal: knowledge is a contract with a read side and a write side; a harvester is a soul type permitted to write knowledge; the write side's doctrine is decision versus description; non-coding specialists are almost pure knowledge; custody scoping belongs to the contract. | `docs/2026-09-03-architecture-proposal.md` (this repository), sections "Soul type", "The slot contracts", "Three simplifications". |
724
+ | 2026-09-03/04 | OATS architecture proposal: knowledge is a contract with a read side and a write side; a harvester is a soul type permitted to write knowledge; the write side's doctrine is decision versus description; non-coding specialists are almost pure knowledge; custody scoping belongs to the contract. | the September 3 architecture proposal (this repository until 0.26.0; in the v0.25.x tags), sections "Soul type", "The slot contracts", "Three simplifications". |
725
725
  | 2026-09-05 to 09-08 | Record-fed harvest shipped: `oats.okf` 1.5.0 to 1.6.1 (record windows, watermark, replan detection, exclusions, harvest runtime and model settings, non-zero exit on failure, inspect view and harvest action). | `capabilities/oats-okf/` at 1.6.1 (this repository); `docs/design/operations-contract.md`. |
726
726
  | 2026-09-07 | Founder: the OATS team holds the agreed architecture vision; OAS-side review is advisory. | Steward note `oats-vision-delegated-to-juan.md`. |
727
727
  | 2026-09-08 | Expert-assisted deployment proposal: shared knowledge collections with explicit promotion destinations; pending-for-owner for ambiguous material; the expert must not become the deployment's database; acceptance is knowledge output, not harvester activity. | `docs/design/2026-09-08-expert-assisted-deployment-proposal.md` (this repository), "Shared knowledge and promotion destinations"; steward note `deployment-as-capability-not-a-layer.md`. |
@@ -700,8 +700,8 @@ feature work forward.
700
700
  ## Current implementation references
701
701
 
702
702
  These provide baseline context, not proof that this proposal is implemented:
703
- - [Package engine](package-engine-contract.md)
704
- - [Package runtime API](package-runtime-api.md)
703
+ - Package engine (`package-engine-contract.md`, removed in 0.26)
704
+ - Package runtime API (`package-runtime-api.md`, removed in 0.26)
705
705
  - [Configuration](../configuration.md)
706
706
  - [Souls and instances](../souls-and-instances.md)
707
707
  - [Multi-team/deployment proposal](2026-09-08-expert-assisted-deployment-proposal.md)
@@ -33,8 +33,8 @@ instance review file or original conversation is an acceptance dependency.
33
33
  | 4 | [Retention contract](2026-09-14-artifact-retention-contract.md) | Landed and binding: store semantics, captured resolution and consumer migration. |
34
34
  | 5 | [Implementation checklist/ledger](2026-09-15-portable-souls-implementation.md) | Clause-by-clause mapping, dependency order, evidence and pending gates. |
35
35
  | 6 | [Knowledge direction](2026-09-13-knowledge-and-memory-direction.md) and [current knowledge runtime](../knowledge.md) | Doctrine/context; the older brief's §4.9 automatic skill-delivery account is superseded by OKF v2 (no automatic soul-skill edits). Its older location/type mechanisms are not a second Portable Souls authority. |
36
- | 7 | [Package engine](package-engine-contract.md) and [runtime API](package-runtime-api.md) | Existing acquisition/trust/runtime invariants; explicit Portable Souls migration changes store/resolution semantics, not silently these contracts. |
37
- | 8 | [Retention source](../../lib/capability-artifacts.mjs) and [tests](../../test/capability-artifacts.test.mjs) | Storage prerequisite; not complete instance/job dispatch. |
36
+ | 7 | Package engine (`package-engine-contract.md`, removed in 0.26) and runtime API (`package-runtime-api.md`, removed in 0.26) | Existing acquisition/trust/runtime invariants; explicit Portable Souls migration changes store/resolution semantics, not silently these contracts. |
37
+ | 8 | Retention source `lib/capability-artifacts.mjs` and its tests (removed in 0.26 with the captured path) | Storage prerequisite; not complete instance/job dispatch. |
38
38
 
39
39
  Implementation baseline: `428cd9af615652c4a93d754c1106674abd18545b` on the isolated
40
40
  `feat/portable-souls-infrastructure` worktree. There is no instruction to merge,
@@ -29,7 +29,7 @@ Binding inputs, all portable repository paths:
29
29
  integration requirements are binding despite the historical heading.
30
30
  - [Reconciled explainer](2026-09-14-portable-souls-explainer.md); LFX examples are
31
31
  hypothetical illustrations, not actual repositories, team setups or credentials.
32
- - [Package engine](package-engine-contract.md), [runtime API](package-runtime-api.md)
32
+ - Package engine (`package-engine-contract.md`, removed in 0.26), runtime API (`package-runtime-api.md`, removed in 0.26)
33
33
  and [current knowledge runtime](../knowledge.md) for preserved contracts.
34
34
  The [older knowledge brief](2026-09-13-knowledge-and-memory-direction.md) provides
35
35
  doctrine, not a competing source/default schema or permission to auto-edit skills.
@@ -25,7 +25,7 @@ Legend: ✅ on main/published · 🔄 in flight (PR/branch) · 🟡 preserved, n
25
25
  - Open: strict-Pi "enriched profile" remains unqualified (documented, not hidden).
26
26
 
27
27
  ## S2 — Workspace adoption of the OATS repos
28
- - ✅ **PR23 merged f6d5a89b**: `oats-workspace.yaml` (7 members, `imports: []`), `oats.yaml` (exports souls/oats-expert, oats-package, capabilities/oats-authoring), transitional `souls/oats-expert/` edition, `docs/workspace-adoption.md`, layout tests.
28
+ - ✅ **PR23 merged f6d5a89b**: `oats-workspace.yaml` (7 members, `imports: []`), `oats.yaml` (exports souls/oats-expert, oats-package, capabilities/oats-authoring), transitional `souls/oats-expert/` edition, the workspace adoption guide (removed in 0.26.0), layout tests.
29
29
  - ✅ **PR24 merged da38e5a9**: deletion of `skills/oats-portable-setup` + `oats inspect --request` read-only seam (ACCEPTED as the public inspection route); full gate 1621/0.
30
30
  - ✅ Member `oats.yaml` merged to main: oats-okf #3 (fec78a20), oats-aweb #1 (069ea2f6), oats-authoring #1 (54183a6a), oats-jira #1 (2f855daf).
31
31
  - ✅ oats-dev#1 (main 6e164ee3) and oats-linear#1 (main a2121e48) merged after Juan granted write access — M's exact commits 0434f4ef / 8c183c37.
@@ -117,7 +117,7 @@ Fresh directory and deployment, `@awebai/oats@0.24.4`, policy sources v2.1.2 / v
117
117
 
118
118
  ## S5 — Official marketplace
119
119
  - ✅ Mechanism exists (`package-catalog.json`, `officialPackageCatalog()`); decision names it the official list.
120
- - ✅ **D4 merged PR26 (786490ae)**: `docs/official-marketplace.md`, `package-catalog.json` policy pointer (inert to the reader), README/packages/capabilities links, D3 sketch in adoption guide. ⬜ entries for `oats.core`/`oats.setup` at D1 release. Desktop view → S8.
120
+ - ✅ **D4 merged PR26 (786490ae)**: the official list policy (now `docs/official-catalog.md`), `package-catalog.json` policy pointer (inert to the reader), README/packages/capabilities links, D3 sketch in adoption guide. ⬜ entries for `oats.core`/`oats.setup` at D1 release. Desktop view → S8.
121
121
 
122
122
  ## S6 — Five expert souls in the oats repo
123
123
  - ✅ **PR30 merged (40a579dc)** + maintainer follow-up **caa341f3**: all five declare `oats.core: {source: repo:oats-package}`, oats.okf@v2.1.1; `oats.yaml` exports all five; `oats-workspace.yaml` imports all five at caa341f3 (375b9f42). Live inspection against published main resolves them.
@@ -462,7 +462,7 @@ stays advertised because the verb still serves classic homes
462
462
  ### 0.25.2 operator-rebuild round (2026-09-24) — appended, not edited in place
463
463
 
464
464
  Source: an operator's first rebuild of a real two-team deployment on 0.25.0,
465
- following `docs/rebuild-to-v2.md` literally. **The guide is a contract the
465
+ following the 0.25 rebuild guide literally (removed in 0.26.0). **The guide is a contract the
466
466
  kernel must honour**: where the guide claimed behaviour the kernel lacked, the
467
467
  kernel changes; where the guide described keys no provider consumes, the guide
468
468
  changes. Findings R1–R10; kernel side in 0.25.2 (`docs/release-notes/v0.25.2.md`).
@@ -29,7 +29,7 @@ Each is one PR (or two small ones), reviewed by me, on `main`, as canonical code
29
29
  | **W8** | **Delete v1** | Remove `portable-*`, `source-spec`, `capability-provenance` (v1 parts), `prepared-resources`, migration stores/evidence, the installed tier in `packages.mjs`, classic config activation, their tests and docs; `core.mjs` loses everything that only served v1 | lead | L (mostly deletion) |
30
30
  | **W9** | **Framework repos as the first workspace (decisions 18–21)** | `oats-workspace.yaml` v2 in `oats` (drop the six imports; `packages:` pins oats.framework/okf/aweb/jira/linear/authoring/dev **as packages**; `teams:` global/engineering; `defaults`); `oats-membership.yaml` in ALL seven repos; the six soul editions rewritten (`oats.okf: {from: package}` etc. even though the repos are members); **a new expert soul in every package repo** — `okf-expert`, `aweb-expert`, `jira-expert`, `linear-expert`, `authoring-expert`, `dev-expert` (v2 `souls/<name>/`, team global, knows and evolves that capability); `package-catalog.json` kept as the official marketplace (bare-version `packages:` entries resolve through it) | lead (member-repo PRs to their owners; the expert souls' AGENTS.md drafted by me, reviewed by the package owner) | L |
31
31
  | **W9b** | **`oats.core` and `oats.setup` rewritten for the new architecture (human, 2026-09-23)** | The two official capabilities' skills and injects are rewritten to teach the *new* model, not patched: **`oats.core`** (`oats-operate`, `oats-souls`, the "you run on OATS" inject) — how an agent works inside an instance under this architecture: its home layout (`.oats/modules/`, `.agents/skills/`, `instance.json` modules/providers), the verbs it will actually use (`status`, `spawn --preview/--provider`, `retire`, `session`, `instance events`, `capabilities`, `souls`, `workspace status`), what a workspace/member/package/team is *from the agent's seat*, drift ("member moved since"), how to find and read other souls. **`oats.setup`** (`oats-config`/`oats-packages` → renamed to what they now are: `oats-workspace`, `oats-packages`, `oats-onboarding`) — the whole architecture and its best practices: workspace ↔ repo handshake and why, `oats-workspace.yaml` / `oats-membership.yaml` / `soul.yaml` v2 / `oats-local.yaml` field by field, teams as labels, member-tier vs package-tier and the non-collapse rule, `packages:` + lock v3 + per-version approval, the official catalog vs `git:` refs, `sync`/`package add`, the deployment directory (the operator's; no naming convention) and clone-then-spawn, private items, external souls, the standalone case, provider payload homes (soul/machine/spawn), what is deliberately NOT versioned and why. Every skill is validated against the shipped CLI (`oats <verb> --help` snapshot test) so they cannot drift from the commands. | lead (swarm + review) | M |
32
- | **W10** | **Docs** | **`docs/rebuild-to-v2.md` — the rebuild guide (ships with the schemas; states that 0.24.x keeps spawning 0.24.x deployments)**; `docs/workspaces.md` rewritten around v2; `souls-and-instances.md`, `packages.md`, `configuration.md` (mostly deleted), `first-team.md` → the operator's deployment directory; DTO doc § Workspace v2; release notes | lead | M |
32
+ | **W10** | **Docs** | **the rebuild guide (removed in 0.26.0; ships with the schemas; states that 0.24.x keeps spawning 0.24.x deployments)**; `docs/workspaces.md` rewritten around v2; `souls-and-instances.md`, `packages.md`, `configuration.md` (mostly deleted), `first-team.md` → the operator's deployment directory; DTO doc § Workspace v2; release notes | lead | M |
33
33
  | **W11** | **Onboarding skill** | `oats-setup-expert` / `oats.setup`: ASK for the deployment directory (an existing folder with the operator's clones is the usual case — no named convention, decision 9), `oats sync`, clone-then-spawn; **the hosting rule for mixed public/private organisations (decision 26): ask up front whether any member is private; if so the workspace file is hosted in a private repo that is NOT a public member (a dedicated private `workspace` repo is the honest shape), public contributors get the standalone case with `oats.core` by default (decision 25); `oats onboard` prints the same rule in its next-steps**; the `oats-operate` skill updated for the new verbs | lead | S |
34
34
  | **W12** | **Desktop follow-through** | New kernel DTOs (from W7) consumed the usual way — engineer reads the merged head, files pins, wires: Capabilities/Souls origin + team columns; "installed" removed as a state; spawn preview shows modules (from/commit/hash) + team; Workspaces surface shows membership status | Desktop engineer, after W7 | M |
35
35
 
@@ -119,6 +119,38 @@ action (`oats retire`) and `--force` behind a confirm.
119
119
  **F5 — Redesign frames** (the original Phase 3 deliverable, excl. 05/06),
120
120
  implemented on top of F1–F4 rather than on the 0.24 model.
121
121
 
122
+ **F7 — Side panels redesigned, teams everywhere (human, 2026-09-25). This
123
+ supersedes the frames and the text above wherever they differ.** One Desktop PR:
124
+ - **Side panels** in the spawn modal's design language (frame 01a):
125
+ - an identity header and compact cards;
126
+ - only useful facts (no "Not reported" rows), and empty sections hidden;
127
+ - relative dates, and shortened paths with Copy;
128
+ - errors as one plain sentence, with the code behind Details;
129
+ - discoverable cross-links between an instance and its soul.
130
+ - **Terminal-side context panel tabs, in order:** Instance · Soul · Git & GitHub.
131
+ - **Teams, per surface** (teams contract `docs/design/2026-09-25-teams-contract.md`):
132
+ - **Soul** (Workspace inspector): the soul's labels, primary marked, each
133
+ joinable or "not mapped by this workspace". Read-only, from
134
+ `inspect --soul` `teams`.
135
+ - **Instance** (Workspace inspector and the terminal-side Instance tab): the
136
+ live panel (#178). Personal is always on; joined teams have Leave, and
137
+ joinable ones have Join.
138
+ - **Spawn modal, main form** (not Developer settings), a Teams row:
139
+ - "Personal team — always", fixed;
140
+ - each joinable label as an unchecked checkbox, sent as
141
+ `--provider <messaging> join=<a,b>`;
142
+ - unmapped labels greyed with the reason;
143
+ - the line "By default it's only in your personal team. Tick the teams it
144
+ should also join."
145
+
146
+ The row is shown iff the preview carries `teams` AND the messaging
147
+ module's preview row lists `join` in `declares` (feature
148
+ `settings-declared`; the Desktop gates on declared facts, never on
149
+ versions).
150
+ - **Second human redirect (QA, same day):** unmapped labels are not shown
151
+ anywhere (no greyed rows, no "not mapped" text), and Teams in the spawn
152
+ modal is one row styled like Relationship.
153
+
122
154
  **F6 — Version and doctor surface.** `oats version --json` and `oats doctor
123
155
  --json` in an About/Health pane; `ACCEPT_RANGE` and the three pins move to
124
156
  `>=0.25.6`; a kernel below the floor is refused with the upgrade command shown.
@@ -131,7 +163,8 @@ spawns children (its call; the lead reviews each PR).
131
163
  Read, in this order, in the checked-out main:
132
164
  1. `docs/workspaces.md` — the v2 model end to end (deployment vs workspace,
133
165
  members, packages, payloads, `byTeam`, hosting).
134
- 2. `docs/rebuild-to-v2.md` — how an operator builds a deployment (this is the
166
+ 2. the 0.25 rebuild guide (removed in 0.26.0; `docs/configuration.md` and
167
+ `oats onboard` now) — how an operator builds a deployment (this is the
135
168
  flow F2 wraps).
136
169
  3. `docs/desktop-cli-api.md` — every JSON surface, with examples; note
137
170
  `features[]`, `decision.effective.providers`, `instances[].identity`.
@@ -167,6 +167,51 @@ Kernel (lead): pass the soul's team label and the workspace identity so the
167
167
  provider derives the personal team deterministically; an unmapped team means
168
168
  "personal". The onboarding skill's manual invite-then-join step is the 1.12.0
169
169
  path and is rewritten when the provider ships R1/R2.
170
+ **Teams, re-stated as THE priority (human, 2026-09-25; amends R1/R2):**
171
+ "As long as we don't have this working seamlessly, people won't understand
172
+ things." The two most important messaging behaviours, above every other
173
+ messaging item:
174
+ - **(R1) A personal team by default.** A user's agents in a workspace get
175
+ that person's personal team for the workspace with no setup step. This is
176
+ the default whenever the workspace maps nothing else.
177
+ - **Defaults and joining (human, later the same day; refines R1/R2′):**
178
+ - By default an instance is in the person's personal team ONLY, even when
179
+ its soul names teams.
180
+ - Joining a wider team is explicit: a spawn choice, or at any point of the
181
+ instance's life one simple command, run by the human, another agent, or
182
+ the instance when told to. It covers only the soul's labels the workspace
183
+ maps.
184
+ - The Desktop offers these controls.
185
+ - Personal teams are per WORKSPACE: one personal team spanning several
186
+ workspaces is wrong, and aweb's per-workspace get-or-create (abjj) is
187
+ urgent. Nobody uses OATS in production yet, which is what keeps this a
188
+ fix and not a migration.
189
+ - Contract: `docs/design/2026-09-25-teams-contract.md`.
190
+ - **(R2′) Wider teams, at spawn AND during an instance's life.** When a soul
191
+ belongs to one or more wider teams, its instance is also included in each
192
+ team the soul specifies, both at spawn and at any later point of its life,
193
+ not only at spawn. The teams are exactly those the workspace defines
194
+ (`messaging.byTeam` / the workspace's team labels); no team outside the
195
+ workspace's definition, and none silently missing. R2′ supersedes R2's
196
+ "is spawned … joins": joining is a lifetime operation, and a soul may name
197
+ several teams.
198
+ Both are oats.aweb's (Antares) with aweb primitives. **The kernel's share is
199
+ the lead's:**
200
+ - today `soul.team` is ONE label (docs/soul.schema.json), and the messaging
201
+ payload merges `byTeam[soul.team]` for that one label. "Team/teams" needs a
202
+ soul to name several team labels, and the payload to carry each mapped
203
+ team's entry (not one merged view), so the provider can join all of them;
204
+ - the workspace identity and the person's identity reach the provider, so
205
+ the personal team derives deterministically;
206
+ - a lifecycle entry point for "join now" during an instance's life (for
207
+ example, a provider operation or hook run against a live home when the
208
+ workspace's teams or the soul's team labels change at a new commit).
209
+ The contract shape is decided with Antares and recorded as a Decision before
210
+ code. **Human, same day:** the primitives must be seamlessly integrated into
211
+ the aweb messaging capability (acceptance is the oats.aweb experience: no
212
+ manual `aw team …` anywhere we ship, and live instances follow the
213
+ workspace's teams), and kernel changes are in scope, so the provider is not
214
+ bent around today's kernel.
170
215
  **Naming (lead, 2026-09-24):** the `oats-` prefix on all six —
171
216
  it matches the repository names and the roster's `oats-kernel-`/`oats-desktop-`/
172
217
  `oats-operator-expert`, and it keeps instance aliases from colliding with the
@@ -211,6 +256,18 @@ the harvester delivers to that node as a PR the owning expert reviews.
211
256
  - **Legacy souls** (`agents/*` and their knowledge bundles) are NOT part of D4:
212
257
  they go when the live instances linking them retire (human rule).
213
258
 
259
+ **Human direction 2026-09-25: runtime → harness** ("throughout the app and cli and everywhere"). It ships in 0.26.0 as one kernel PR after (e):
260
+ - every kernel-owned name is renamed with no alias (`--harness`, `launch-configs.<n>.harness`, `instance.json.harness`, JSON fields, feature `harness`);
261
+ - two released-contract aliases stay: the provider env sets both `OATS_HARNESS` and `OATS_RUNTIME`, and manifests may say `requires[].runtime` or `requires[].harness`;
262
+ - the Desktop switches on the `harness` feature.
263
+
264
+ **Human direction 2026-09-25 (~17:20Z), amending the above: release 0.26.0 WITHOUT the harness rename; harness ships as a separate, later release.**
265
+ - 0.26.0 ships main as it stands once the in-flight PRs land: (e), K, the teamsOf check, `layers.<layer>.from`, and Desktop F7. It keeps the `runtime` names everywhere.
266
+ - The harness rename (the kernel PR, with the alias addendum: env `OATS_RUNTIME`, stdin `launch.runtime`, manifest `agents[].runtime`/`requires[].runtime`, `spawn --runtime`) ships in the **next minor, 0.27.0**. It is a breaking CLI/JSON change (`--runtime` refused on session/launch-config, `version.runtimes` dropped, launch-configs field renamed), so it isn't a patch. It ships together with the Desktop's switch on feature `harness`, and the Desktop's accepted kernel range widens to include 0.27.
267
+ - Neither the kernel harness PR nor the Desktop switch merges to main before the v0.26.0 tag.
268
+
269
+ Also: "core capabilities" is the human vocabulary for the knowledge/messaging/tasks capabilities in prose; wire names are unchanged.
270
+
214
271
  ### D5 — Catalog update and 0.26.0
215
272
 
216
273
  Catalog pins for the new package versions; **widen Desktop `ACCEPT_RANGE` and
@@ -0,0 +1,226 @@
1
+ # Teams contract: several team labels per soul, per-team messaging, live reconciliation
2
+
3
+ Status: AGREED 2026-09-25 by both co-leads (provider verbs confirmed in e205c93a). First drafted by the lead (kernel lane), with the messaging
4
+ co-lead's provider plan. It serves the human priority of 2026-09-25, recorded
5
+ in `2026-09-24-phase-d-plan.md` under "Teams, re-stated as THE priority".
6
+ This document is the kernel half; the provider half (oats.aweb) is the
7
+ messaging lane's. Co-lead review (9a18a381): agreed, with three additions,
8
+ folded in below.
9
+
10
+ ## The model (human, 2026-09-25)
11
+
12
+ - **Default: the personal team only.** Every instance is in its person's
13
+ personal team for THIS workspace. A soul's `team` labels do NOT put it
14
+ in those teams by default.
15
+ - **Joining is explicit.** A wider team is joined by an explicit action:
16
+ - at spawn, a spawn choice;
17
+ - or at any point of the instance's life, one simple command, run by the
18
+ human, by another agent, or by the instance itself when told to.
19
+ - **Only what the soul and workspace allow.** The teams an instance MAY join
20
+ are exactly its soul's labels that the workspace maps. Nothing else is
21
+ offered or accepted.
22
+ - **Leaving** is the same kind of command. When the workspace removes a
23
+ mapping or the soul drops a label, the joined membership for it is left.
24
+ - **The Desktop has controls for it:** at spawn (which eligible teams to
25
+ join) and on a live instance (join/leave, and the joined vs eligible
26
+ teams).
27
+ - **Personal teams are per WORKSPACE.** One personal team spanning several
28
+ workspaces is wrong. Until aweb ships the per-workspace get-or-create, the
29
+ person's single default team is an explicitly temporary stand-in.
30
+
31
+ ## Problem
32
+
33
+ - A v2 soul names ONE team label (`soul.yaml` `team`, else the repository's
34
+ default from `oats-membership.yaml`).
35
+ - The resolver merges `workspace.messaging ⊕ byTeam[<that label>]` into one
36
+ messaging payload, and applies `defaults.byTeam[<that label>].capabilities`
37
+ to the soul's composition.
38
+ - An instance can therefore be placed in one team only, and only at spawn.
39
+ - The human's bar: a person's agents are in their personal team by default,
40
+ AND in every wider team their soul belongs to, at spawn and during the
41
+ instance's life, and those teams are exactly the ones the workspace defines.
42
+
43
+ ## Decision
44
+
45
+ 1. **Several labels.**
46
+ - `soul.yaml` `team` accepts a label or a non-empty list of distinct
47
+ labels: `team: dev` or `team: [dev, reviewers]`.
48
+ - `oats-membership.yaml`'s repository default takes the same shape.
49
+ - The FIRST label is the **primary**. A single string is a one-element
50
+ list, so existing souls don't change.
51
+ 2. **Composition (`defaults.byTeam[*].capabilities`).**
52
+ - Applied for every label, in soul order, after `defaults.capabilities`
53
+ and before the soul's own `capabilities`. The soul's own entries still
54
+ win.
55
+ - Two labels that give the same capability different entries is
56
+ `E_TEAM_CONFLICT`, naming both labels. There's no silent
57
+ last-writer-wins. Identical entries from two labels are not a
58
+ conflict.
59
+ 3. **Messaging payload.**
60
+ - **Amended (K, co-lead ruling on the 1.14.0 review):** the messaging
61
+ provider's merged settings are `base ⊕ soul ⊕ host ⊕ spawn`, and **no
62
+ `byTeam[<label>]` is merged into them**, the primary's included. Each
63
+ label's `base ⊕ byTeam[label]` lives only in its `teams` entry (below).
64
+ So `settings.team` / `OATS_TEAM_ID` mean "the personal team, if the
65
+ host, soul or spawn set one"; empty means the provider's own default
66
+ (for oats.aweb, the root's active team). Reason: the instance is
67
+ personal-by-default (the human's model), and the primary label is just
68
+ the first eligible team. Merging its payload made the provider mint the
69
+ primary identity into the mapped team, and it couldn't tell a host-set
70
+ personal team from the workspace's mapped one.
71
+ - New and kernel-owned: `teams`, an ordered list of
72
+ `{ label, mapped: boolean, payload }`.
73
+ - `payload` is `base ⊕ byTeam[label]` when the workspace maps the label.
74
+ - It's `base` alone, with `mapped: false`, when the label isn't mapped.
75
+ - Each entry also carries the resolved team id as `team` (null when the
76
+ label isn't mapped), so a provider never digs it out of `payload`.
77
+ "Personal" is the provider's to resolve; the kernel says nothing about
78
+ it.
79
+ - These are the **eligible** teams. Joining them is explicit (see "The
80
+ model"), not automatic.
81
+ - It's delivered beside the settings, in the environment (`OATS_TEAMS` JSON),
82
+ never inside the provider's own settings object, so it can't collide
83
+ with a provider key or its manifest's settings validation.
84
+ - `teams` is present when the soul has a label; a soul with no label gets
85
+ `[]`, meaning "personal only".
86
+ 4. **Environment.**
87
+ - `OATS_TEAM_LABEL` / `OATS_TEAM_ID` stay the primary's.
88
+ - New: `OATS_TEAM_LABELS` (all labels, comma-joined, in order) and
89
+ `OATS_TEAMS` (the JSON above).
90
+ - New: `OATS_TEAMS_SOURCE`, which is `live` or `recorded` (decision 6). It's empty
91
+ when `OATS_TEAMS` is empty (unknown).
92
+ - **The environment is the only channel.** No stdin wire gains keys: the
93
+ binding check's request stays exactly the released wire, because released
94
+ providers (oats.aweb 1.13.1) key it strictly and refuse unknown keys with
95
+ `invalid-binding`. A provider check reads the teams from the same env
96
+ variables its hooks get. (Correction after #179, co-lead finding.)
97
+ - Workspace identity is unchanged: `OATS_WORKSPACE_KEY` / `OATS_WORKSPACE_NAME`.
98
+ - The person's identity stays the provider's (its messaging root from host
99
+ settings); the kernel passes the deployment, as today.
100
+ 5. **Discovery.**
101
+ - A label the workspace doesn't map is a discovery **warning**
102
+ (`unmapped-team-label`), not an error, so the provider can fall back to
103
+ the personal team and say so.
104
+ - There's one warning per unmapped label, naming its souls
105
+ (`{ code, label, souls, paths, message }`), not one per soul and label.
106
+ A workspace with no `messaging.byTeam` must not print a line per soul.
107
+ - A label that isn't in the workspace's `teams:` list at all stays the
108
+ error it is today.
109
+ 6. **Live resolution for a home.**
110
+ - A home's teams are **live messaging state, not frozen composition**. The
111
+ modules and skills an instance got at spawn don't change under it; which
112
+ teams it belongs to follows the workspace.
113
+ - For home-context provider operations and the launch hook, the kernel
114
+ computes `teams` from the soul's labels at the soul commit the
115
+ deployment currently resolves (the lock), and the workspace's current
116
+ `messaging`.
117
+ - That lets the provider offer a team the workspace added as eligible,
118
+ and leave one it removed, without a respawn.
119
+ - The recorded spawn-time `teams` stays in `instance.json.teams` as
120
+ evidence: beside `providers`, never inside that capability-keyed map.
121
+ - **Live or recorded.** When the workspace can't be read now (the host is
122
+ offline, or the soul is no longer listed), the kernel falls back to the
123
+ recorded set and says so: `OATS_TEAMS_SOURCE=recorded`, or
124
+ `teamsSource: "recorded"` in inspect.
125
+ - **A provider leaves a joined team only on a `live` answer.** On
126
+ `recorded` or unknown it keeps every membership and may warn
127
+ (`teams-unverified`).
128
+ - Reason: a team mapped after spawn and joined live is absent from the
129
+ record, and an offline host must never cost an instance a membership.
130
+ - **Cost.** Live teams are computed only where they're consumed:
131
+ - session start/restart;
132
+ - the messaging module's own home-context commands and operations;
133
+ - `inspect` / `readiness --home`.
134
+
135
+ The live read covers the workspace host and the soul's repo, not a full
136
+ workspace discovery. Every other in-home capability command uses the
137
+ record and costs what it did before.
138
+ - **0.26.0 limitation:** a scheduled wake's start uses the spawn-time teams.
139
+ The scheduler is synchronous; only operator starts are live.
140
+ - **Retire** works from the provider's own recorded membership list,
141
+ never from the live eligible set. A mapping removed after the spawn
142
+ still has its membership revoked at retire.
143
+ 7. **Explicit join, spawn choice, Desktop.**
144
+ - The join/leave/list verbs are the provider's (oats.aweb 1.14.0), run
145
+ inside a home or with `--home <abs>`, all idempotent, all with `--json`:
146
+ - `oats aweb teams` answers
147
+ `{ personal: {team}, primary, eligible: [{label, team, joined}], joined: [{label, team, since, identityHome, receive}], unmapped: [label], at }`, where `receive` is `native` or `poll`;
148
+ - `oats aweb join <label>[,<label>]` and
149
+ `oats aweb leave <label>[,<label>]` answer the same document. The
150
+ personal team can't be left (`E_TEAM_PERSONAL`).
151
+ - The same verbs are declared as home-context operations
152
+ `messaging:teams|join|leave`, so the Desktop uses `oats operation run`
153
+ and needs no new kernel surface.
154
+ All three are `kind: action` (the default): a `view` must answer
155
+ `{documents:[…]}` (markdown/text for reading), and the teams document
156
+ is structured JSON. `messaging:teams` is read-only by its own
157
+ contract, which its description says. Join and leave declare one
158
+ required arg, `labels` (flag `--labels`, comma-separated).
159
+ - Identity model: one local identity per joined team, under the home as
160
+ `.aweb-identity-<label>`. The personal-team identity is the primary one,
161
+ wired to the harness. There are no global identities by default.
162
+ - **Sending and receiving as a joined team (oats.aweb 1.14.0):**
163
+ - Sending is complete: `aw --identity-home <identityHome> mail|chat …`,
164
+ the one form the aweb inject teaches.
165
+ - Receiving is by POLL: the channel plugin, the pi extension and a wake
166
+ registration each listen on one identity home. The inject says to
167
+ check a joined team's inbox at task boundaries, and readiness and
168
+ `receive: poll` say so.
169
+ - Native receive for joined teams needs one of two aweb primitives:
170
+ wake/channel on several identity homes per instance home, or global
171
+ instance identities with address release (one identity, many teams,
172
+ one channel). This is a named gap against the "seamless" bar,
173
+ tracked as an aweb ask.
174
+ - Each is idempotent, and refuses a label the instance isn't eligible for
175
+ (`E_TEAM_NOT_ELIGIBLE`, naming the eligible labels).
176
+ - **Declared setting keys (added after #179):** the spawn preview's
177
+ `modules[]` rows and `inspect`'s `capabilities[]` rows carry
178
+ `declares: [<setting key>…]` (names only; feature `settings-declared`).
179
+ That's how a Desktop sees that the messaging manifest declares
180
+ `settings.join` without reading manifests.
181
+ - `inspect --soul` on a soul whose labels conflict (`E_TEAM_CONFLICT`)
182
+ refuses. The error details name the capability and both labels; no
183
+ `teams` is answered, because the soul can't be spawned until the
184
+ workspace resolves it.
185
+ - At spawn, the kernel carries the operator's choice to the provider as a
186
+ spawn provider setting (`--provider <messaging> join=<label>[,<label>]`).
187
+ That needs no new kernel flag, and the spawn preview shows it.
188
+ - The launch hook re-checks joined memberships against the live eligible
189
+ set: it leaves what's no longer eligible (only when
190
+ `OATS_TEAMS_SOURCE=live`, decision 6) and never joins on its own.
191
+ - **The kernel puts `teams` (eligible, the OATS_TEAMS entries) in the
192
+ spawn preview and in `inspect --home`**, so a Desktop can offer the
193
+ choice before anything is minted. The Desktop reads that, plus joined memberships from the provider's inspect or
194
+ operation, and drives the same verbs.
195
+ - Later kernel item: `oats sync` reports the souls whose labels or
196
+ mappings changed since the previous lock.
197
+
198
+ ## Compatibility
199
+
200
+ - A single-label soul sees byte-identical **composition** (modules, skills,
201
+ injects). Its messaging **payload** changes: the mapped label's `byTeam`
202
+ entry is no longer merged into the provider's settings; it's only in
203
+ `OATS_TEAMS` (amendment K). With 0.26.0 + oats.aweb 1.13.1, the primary
204
+ identity therefore mints into the personal (root-active) team, as the
205
+ human's model wants.
206
+ - oats.aweb 1.13.1 ignores `OATS_TEAMS` and keeps working, because no stdin
207
+ wire changes (its binding decoder refuses unknown request keys).
208
+ - oats.aweb 1.14.0 reads them.
209
+ - The schema change goes into 0.26.0, the release that already breaks the
210
+ file formats.
211
+
212
+ ## Tests
213
+
214
+ - Several labels compose in order; a conflict → `E_TEAM_CONFLICT`. A
215
+ capability the soul names itself is exempt, since the soul's entry wins over
216
+ every label.
217
+ - A mapped primary's `byTeam` payload is absent from the provider's merged
218
+ settings and present in `OATS_TEAMS[0].payload` (amendment K).
219
+ - `OATS_TEAMS` shape: mapped and unmapped labels, and no label → `[]`.
220
+ - Home-context `teams` follows a new workspace commit (a mapping added and
221
+ removed) while the home's modules stay frozen.
222
+ - Discovery warns once per unmapped label.
223
+ - A home whose workspace can't be read gets the record with
224
+ `OATS_TEAMS_SOURCE=recorded`; a non-messaging in-home command runs no live
225
+ team read.
226
+ - `teams` entries carry `team`; identical cross-label entries don't conflict.
@@ -7,12 +7,12 @@ Dated design documents record how decisions were reached and what each implement
7
7
  - **[Workspace module contracts (2026-09-23)](2026-09-23-workspace-module-contracts.md) — NORMATIVE for implementation**: `lib/remote.mjs`, `lib/workspace.mjs`, `lib/resolve.mjs`, `lib/packages.mjs` (lock v3), `lib/materialize.mjs`, the CLI verbs and DTOs, the error codes, the Northwind fixture.
8
8
  - [Simplified workspace model — worked example (2026-09-23)](2026-09-23-simplified-workspace-model.md) — ACCEPTED: one workspace per org, membership = trust, `from:` as location, nothing installed, full per-instance copy, teams as labels, harnesses start normally. The Decision concept is `agents/oats-expert/soul/knowledge/decisions/workspace-model-v2.md`.
9
9
  - [Implementation plan (2026-09-23)](2026-09-23-workspace-v2-implementation-plan.md) — phases A/B/C, what each deletes.
10
- - Operator-facing: [rebuild guide](../rebuild-to-v2.md) (0.24.x → v2; no converter), [Desktop CLI API — workspace model](../desktop-cli-api.md#workspace-model-workspaceapi-2).
10
+ - Operator-facing: [workspace model](../workspaces.md), [Desktop CLI API — workspace model](../desktop-cli-api.md#workspace-model-workspaceapi-2).
11
11
  - Open threads (tracked here until closed): the `workspace` work mode still derives its `./work` boundary from the classic `team:` scope; the readiness `enrolled` producer still reads the 0.24 `oats.yaml` backlink; launch configurations / yolo / work-mode setup are still read from a classic config chain.
12
12
 
13
13
  ## Superseded by the workspace model
14
14
 
15
- Everything below this line that describes per-soul `source:` provenance, `oats.yaml` exports/imports, the installed-capability tier (`.agents/capabilities/installed/`), `oats-config.yaml` scopes, `oats init`/`use`/`install`/`restore`/`trust`/`migrate`, lock v1/v2 or ambient-skill exclusion at launch is **history**. In particular [package-engine-contract.md](package-engine-contract.md) and [package-runtime-api.md](package-runtime-api.md) describe the removed acquisition/materialization engine; the package tier is now [packages.md](../packages.md) + module contract §4. Capability **manifests**, hooks, the operations contract, provider binding wire/codecs and the knowledge/messaging capability contracts are unchanged.
15
+ Everything below this line that describes per-soul `source:` provenance, `oats.yaml` exports/imports, the installed-capability tier (`.agents/capabilities/installed/`), `oats-config.yaml` scopes, `oats init`/`use`/`install`/`restore`/`trust`/`migrate`, lock v1/v2 or ambient-skill exclusion at launch is **history**. In particular `package-engine-contract.md` and `package-runtime-api.md` (both deleted in 0.26) described the removed acquisition/materialization engine; the package tier is now [packages.md](../packages.md) + module contract §4. Capability **manifests**, hooks, the operations contract, provider binding wire/codecs and the knowledge/messaging capability contracts are unchanged.
16
16
 
17
17
  ## Earlier plan (0.24)
18
18
 
@@ -38,7 +38,7 @@ Everything below this line that describes per-soul `source:` provenance, `oats.y
38
38
 
39
39
  ## Capabilities and providers
40
40
 
41
- - [Package engine contract](package-engine-contract.md) · [package-runtime API](package-runtime-api.md) — **superseded** (installed tier removed; see [packages](../packages.md)) · [operations contract](operations-contract.md) · [launch configurations](launch-configurations.md).
41
+ - Package engine contract (`package-engine-contract.md`, removed in 0.26) · package-runtime API (`package-runtime-api.md`, removed in 0.26) — **superseded** (installed tier removed; see [packages](../packages.md)) · [operations contract](operations-contract.md) · [launch configurations](launch-configurations.md).
42
42
  - [Provider binding wire v1](2026-09-16-provider-binding-wire.md) · [provider binding codecs](2026-09-16-provider-binding-codecs.md) · [capability helper/input contract](2026-09-17-capability-helper-input-contract.md).
43
43
  - [Knowledge capability contract](2026-09-16-knowledge-capability-contract.md) · [messaging capability contract](2026-09-16-messaging-capability-contract.md).
44
44