@awebai/oats 0.29.4 → 0.30.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 (224) hide show
  1. package/README.md +12 -6
  2. package/bin/oats.mjs +194 -50
  3. package/capabilities/oats-aweb/bin/oats-aweb.mjs +538 -204
  4. package/capabilities/oats-aweb/injects/aweb.md +1 -1
  5. package/capabilities/oats-aweb/lib/binding-wire.mjs +31 -22
  6. package/capabilities/oats-aweb/oats.json +5 -12
  7. package/capabilities/oats-aweb/skills/VENDORED.md +4 -4
  8. package/capabilities/oats-aweb/skills/aweb-team-membership/SKILL.md +1 -1
  9. package/capabilities/oats-aweb/skills/oats-aweb/SKILL.md +83 -13
  10. package/capabilities/oats-code-review/injects/reviewer.md +26 -0
  11. package/capabilities/oats-code-review/oats.json +16 -0
  12. package/capabilities/oats-code-review/skills/adversarial-review/SKILL.md +66 -0
  13. package/capabilities/oats-code-review/skills/review-dev-docs/SKILL.md +30 -0
  14. package/capabilities/oats-code-review/skills/security-review/SKILL.md +56 -0
  15. package/capabilities/oats-code-review/skills/simplification-review/SKILL.md +34 -0
  16. package/capabilities/oats-developer/injects/developer.md +38 -0
  17. package/capabilities/oats-developer/oats.json +17 -0
  18. package/capabilities/oats-developer/skills/execution-strategy/SKILL.md +43 -0
  19. package/capabilities/oats-developer/skills/maintain-dev-docs/SKILL.md +47 -0
  20. package/capabilities/oats-developer/skills/run-the-review-loop/SKILL.md +65 -0
  21. package/capabilities/oats-developer/skills/understand-the-spec/SKILL.md +37 -0
  22. package/capabilities/oats-developer/skills/worktrees/SKILL.md +36 -0
  23. package/capabilities/oats-engineering-expert/injects/expert.md +37 -0
  24. package/capabilities/oats-engineering-expert/oats.json +17 -0
  25. package/capabilities/oats-engineering-expert/skills/coordinate-developers/SKILL.md +37 -0
  26. package/capabilities/oats-engineering-expert/skills/coordinate-experts/SKILL.md +52 -0
  27. package/capabilities/oats-engineering-expert/skills/land-your-prs/SKILL.md +50 -0
  28. package/capabilities/oats-engineering-expert/skills/plan-and-spec/SKILL.md +53 -0
  29. package/capabilities/oats-engineering-expert/skills/verify-developer-work/SKILL.md +49 -0
  30. package/capabilities/oats-okf/bin/oats-okf.mjs +8 -4
  31. package/capabilities/oats-okf/lib/binding-wire.mjs +47 -15
  32. package/capabilities/oats-okf/lib/inspection.mjs +26 -7
  33. package/capabilities/oats-okf/lib/sources.mjs +16 -2
  34. package/capabilities/oats-okf/lib/worker.mjs +5 -16
  35. package/capabilities/oats-okf/oats.json +6 -3
  36. package/capabilities/oats-okf-harvest/bin/okf-harvest.mjs +2 -2
  37. package/capabilities/oats-okf-harvest/oats.json +3 -3
  38. package/capabilities/oats-okf-harvest/skills/knowledge-harvest/SKILL.md +6 -6
  39. package/capabilities/oats-okf-maintenance/bin/okf-maintenance.mjs +2 -2
  40. package/capabilities/oats-okf-maintenance/injects/maintainer.md +1 -1
  41. package/capabilities/oats-okf-maintenance/oats.json +2 -2
  42. package/capabilities/oats-okf-maintenance/skills/knowledge-review/SKILL.md +1 -1
  43. package/capabilities/oats-okf-maintenance/skills/okf-trigger-setup/SKILL.md +11 -23
  44. package/capabilities/oats-workspace-experts/injects/oats-experts.md +26 -0
  45. package/capabilities/oats-workspace-experts/oats.json +9 -0
  46. package/docs/capabilities.md +160 -171
  47. package/docs/capability-manifest.schema.json +6 -11
  48. package/docs/configuration.md +213 -64
  49. package/docs/design/2026-09-16-knowledge-capability-contract.md +36 -50
  50. package/docs/design/2026-09-23-workspace-module-contracts.md +377 -544
  51. package/docs/design/2026-09-26-okf-knowledge-operations.md +132 -357
  52. package/docs/design/2026-09-27-team-model-v2.md +97 -117
  53. package/docs/design/2026-09-28-automations-trust.md +38 -0
  54. package/docs/design/2026-09-28-soul-launch-preference.md +63 -0
  55. package/docs/design/HISTORY.md +65 -0
  56. package/docs/design/README.md +23 -54
  57. package/docs/desktop-cli-api.md +1787 -1777
  58. package/docs/desktop.md +30 -91
  59. package/docs/execution-targets.md +146 -292
  60. package/docs/first-team.md +31 -17
  61. package/docs/implementation.md +76 -288
  62. package/docs/integrations.md +118 -320
  63. package/docs/knowledge-capability-authoring.md +25 -52
  64. package/docs/knowledge-reference/acceptance.md +3 -3
  65. package/docs/knowledge-reference/adoption.md +1 -1
  66. package/docs/knowledge-reference/harvester.md +2 -2
  67. package/docs/knowledge-reference/package-craft.md +3 -3
  68. package/docs/knowledge-reference/provider-mapping.md +3 -6
  69. package/docs/knowledge-reference/reader-capture.md +3 -3
  70. package/docs/knowledge-theory.md +62 -166
  71. package/docs/knowledge.md +225 -404
  72. package/docs/layers.md +42 -97
  73. package/docs/oats-local.schema.json +58 -5
  74. package/docs/oats-membership.schema.json +1 -8
  75. package/docs/oats-package.schema.json +5 -5
  76. package/docs/oats-workspace.schema.json +8 -22
  77. package/docs/official-catalog.md +25 -28
  78. package/docs/packages.md +45 -63
  79. package/docs/plans/0.30-close-out.md +61 -0
  80. package/docs/release-lane.md +77 -0
  81. package/docs/release-notes/oats-framework-v1.1.3.md +10 -8
  82. package/docs/release-notes/v0.19.0.md +48 -147
  83. package/docs/release-notes/v0.19.1.md +2 -3
  84. package/docs/release-notes/v0.19.3.md +2 -15
  85. package/docs/release-notes/v0.20.0.md +0 -15
  86. package/docs/release-notes/v0.22.0.md +71 -138
  87. package/docs/release-notes/v0.22.1.md +42 -90
  88. package/docs/release-notes/v0.22.10.md +1 -1
  89. package/docs/release-notes/v0.22.11.md +1 -47
  90. package/docs/release-notes/v0.22.12.md +4 -13
  91. package/docs/release-notes/v0.22.13.md +1 -42
  92. package/docs/release-notes/v0.22.14.md +3 -11
  93. package/docs/release-notes/v0.22.15.md +1 -46
  94. package/docs/release-notes/v0.22.16.md +6 -8
  95. package/docs/release-notes/v0.22.18.md +1 -99
  96. package/docs/release-notes/v0.22.19.md +3 -14
  97. package/docs/release-notes/v0.22.2.md +6 -15
  98. package/docs/release-notes/v0.22.3.md +0 -1
  99. package/docs/release-notes/v0.22.4.md +1 -14
  100. package/docs/release-notes/v0.22.5.md +2 -12
  101. package/docs/release-notes/v0.22.6.md +0 -3
  102. package/docs/release-notes/v0.23.0.md +9 -25
  103. package/docs/release-notes/v0.23.1.md +9 -25
  104. package/docs/release-notes/v0.23.2.md +2 -4
  105. package/docs/release-notes/v0.24.0.md +56 -97
  106. package/docs/release-notes/v0.24.1.md +7 -11
  107. package/docs/release-notes/v0.24.10.md +34 -45
  108. package/docs/release-notes/v0.24.11.md +12 -20
  109. package/docs/release-notes/v0.24.12.md +35 -48
  110. package/docs/release-notes/v0.24.13.md +34 -41
  111. package/docs/release-notes/v0.24.2.md +9 -13
  112. package/docs/release-notes/v0.24.3.md +7 -11
  113. package/docs/release-notes/v0.24.4.md +6 -6
  114. package/docs/release-notes/v0.24.5.md +6 -10
  115. package/docs/release-notes/v0.24.6.md +2 -5
  116. package/docs/release-notes/v0.24.7.md +46 -75
  117. package/docs/release-notes/v0.24.8.md +58 -96
  118. package/docs/release-notes/v0.24.9.md +38 -54
  119. package/docs/release-notes/v0.25.0.md +59 -76
  120. package/docs/release-notes/v0.25.1.md +57 -81
  121. package/docs/release-notes/v0.25.2.md +51 -70
  122. package/docs/release-notes/v0.25.3.md +11 -13
  123. package/docs/release-notes/v0.25.4.md +9 -13
  124. package/docs/release-notes/v0.25.5.md +3 -5
  125. package/docs/release-notes/v0.25.6.md +20 -29
  126. package/docs/release-notes/v0.25.7.md +5 -7
  127. package/docs/release-notes/v0.25.8.md +26 -39
  128. package/docs/release-notes/v0.26.0.md +175 -646
  129. package/docs/release-notes/v0.27.0.md +4 -5
  130. package/docs/release-notes/v0.27.1.md +4 -6
  131. package/docs/release-notes/v0.27.2.md +1 -1
  132. package/docs/release-notes/v0.28.0.md +57 -124
  133. package/docs/release-notes/v0.29.0.md +89 -208
  134. package/docs/release-notes/v0.29.1.md +1 -1
  135. package/docs/release-notes/v0.29.2.md +3 -4
  136. package/docs/release-notes/v0.30.0.md +205 -0
  137. package/docs/schedules.md +280 -363
  138. package/docs/servers.md +99 -117
  139. package/docs/soul.schema.json +2 -9
  140. package/docs/souls-and-instances.md +145 -158
  141. package/docs/workspaces.md +132 -215
  142. package/lib/automations.mjs +21 -6
  143. package/lib/core.mjs +226 -74
  144. package/lib/instance-events.mjs +1 -1
  145. package/lib/instance-inspect.mjs +109 -34
  146. package/lib/instance-lifecycle.mjs +14 -1
  147. package/lib/instance-resolution.mjs +26 -27
  148. package/lib/launch-preference.mjs +87 -0
  149. package/lib/materialize.mjs +3 -3
  150. package/lib/resolve.mjs +29 -87
  151. package/lib/schedule.mjs +1 -1
  152. package/lib/teams-verbs.mjs +195 -0
  153. package/lib/teams.mjs +190 -0
  154. package/lib/triggers.mjs +2 -2
  155. package/lib/workspace.mjs +54 -147
  156. package/package-catalog.json +9 -15
  157. package/package.json +1 -1
  158. package/skills/oats-getting-started/SKILL.md +25 -13
  159. package/capabilities/oats-review/injects/review.md +0 -69
  160. package/capabilities/oats-review/oats.json +0 -10
  161. package/capabilities/oats-review/skills/code-review/SKILL.md +0 -44
  162. package/capabilities/oats-review/skills/security-review/SKILL.md +0 -59
  163. package/docs/conventions.md +0 -90
  164. package/docs/design/2026-09-07-architecture-reassessment.md +0 -131
  165. package/docs/design/2026-09-07-desktop-souls-capabilities.md +0 -50
  166. package/docs/design/2026-09-07-mobile-agent-management-proposal.md +0 -228
  167. package/docs/design/2026-09-08-expert-assisted-deployment-proposal.md +0 -558
  168. package/docs/design/2026-09-13-knowledge-and-memory-direction.md +0 -744
  169. package/docs/design/2026-09-13-knowledge-implementation.md +0 -127
  170. package/docs/design/2026-09-13-knowledge-location-contract.md +0 -340
  171. package/docs/design/2026-09-14-artifact-retention-contract.md +0 -190
  172. package/docs/design/2026-09-14-portable-souls-and-git-workspaces.md +0 -708
  173. package/docs/design/2026-09-14-portable-souls-contract-amendments.md +0 -85
  174. package/docs/design/2026-09-14-portable-souls-explainer.md +0 -750
  175. package/docs/design/2026-09-15-captured-dispatch.md +0 -127
  176. package/docs/design/2026-09-15-captured-resolution-records.md +0 -143
  177. package/docs/design/2026-09-15-package-preparation.md +0 -100
  178. package/docs/design/2026-09-15-portable-data-contract.md +0 -121
  179. package/docs/design/2026-09-15-portable-declarations.md +0 -189
  180. package/docs/design/2026-09-15-portable-souls-handoff.md +0 -150
  181. package/docs/design/2026-09-15-portable-souls-implementation.md +0 -417
  182. package/docs/design/2026-09-15-selection-lock-and-approval.md +0 -122
  183. package/docs/design/2026-09-15-source-observation.md +0 -119
  184. package/docs/design/2026-09-16-captured-admission.md +0 -77
  185. package/docs/design/2026-09-16-captured-helper-dispatch.md +0 -105
  186. package/docs/design/2026-09-16-captured-launch-inputs.md +0 -42
  187. package/docs/design/2026-09-16-command-profile-preparation.md +0 -86
  188. package/docs/design/2026-09-16-fresh-install-first-rollout.md +0 -47
  189. package/docs/design/2026-09-16-fresh-operator-walkthrough.md +0 -282
  190. package/docs/design/2026-09-16-messaging-capability-contract.md +0 -59
  191. package/docs/design/2026-09-16-portable-migration-evidence.md +0 -158
  192. package/docs/design/2026-09-16-portable-onboarding.md +0 -179
  193. package/docs/design/2026-09-16-prepare-request-transport.md +0 -26
  194. package/docs/design/2026-09-16-provider-binding-codecs.md +0 -98
  195. package/docs/design/2026-09-16-provider-binding-wire.md +0 -274
  196. package/docs/design/2026-09-17-capability-helper-input-contract.md +0 -95
  197. package/docs/design/2026-09-17-captured-backend-parity.md +0 -53
  198. package/docs/design/2026-09-17-captured-native-start.md +0 -58
  199. package/docs/design/2026-09-17-portable-boundary-hookup.md +0 -19
  200. package/docs/design/2026-09-17-portable-boundary-resources.md +0 -52
  201. package/docs/design/2026-09-17-public-captured-start.md +0 -108
  202. package/docs/design/2026-09-17-public-prepare-request.md +0 -90
  203. package/docs/design/2026-09-18-captured-pi-host.md +0 -205
  204. package/docs/design/2026-09-18-first-cut-release-checklist.md +0 -131
  205. package/docs/design/2026-09-18-herdr-protocol-compatibility.md +0 -60
  206. package/docs/design/2026-09-20-redesign-program-board.md +0 -142
  207. package/docs/design/2026-09-20-workspace-and-portable-adoption-plan.md +0 -289
  208. package/docs/design/2026-09-20-workspace-onboarding-public.md +0 -207
  209. package/docs/design/2026-09-22-desktop-parity-seams.md +0 -58
  210. package/docs/design/2026-09-23-simplified-workspace-model.md +0 -711
  211. package/docs/design/2026-09-23-workspace-v2-implementation-plan.md +0 -65
  212. package/docs/design/2026-09-24-desktop-phase-f-boundary.md +0 -242
  213. package/docs/design/2026-09-24-phase-d-plan.md +0 -305
  214. package/docs/design/2026-09-25-teams-contract.md +0 -258
  215. package/docs/design/2026-09-26-desktop-design-brief-architecture.md +0 -241
  216. package/docs/design/desktop-ux-plan.md +0 -362
  217. package/docs/design/launch-configurations.md +0 -168
  218. package/docs/design/okf-mirror-provenance.md +0 -105
  219. package/docs/design/operations-contract.md +0 -141
  220. package/docs/oats-member.schema.json +0 -38
  221. package/skills/integration-authoring/SKILL.md +0 -84
  222. package/skills/oats-support/SKILL.md +0 -79
  223. package/skills/skill-craft/SKILL.md +0 -109
  224. package/skills/soul-craft/SKILL.md +0 -116
@@ -1,258 +0,0 @@
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
- ## AMENDMENT 2026-09-26 (Juan, a total blocker): there is no "personal team"
11
-
12
- There is **no "personal team" concept**, in aweb or in OATS. **A workspace has its
13
- DEFAULT TEAM** (the team for the workspace key in its owner's namespace);
14
- agents can join other teams. Nothing is "personal". Everywhere below, read
15
- "personal team" as **"the workspace's default team"** (short: "default team").
16
- The rename is applied everywhere, with no compatibility aliases:
17
-
18
- - **Prose:** docs, skills, injects, READMEs, release notes (from 0.29.3 on), the
19
- knowledge base. Past release notes and append-only logs stay as history.
20
- - **Wire names (the oats.aweb 1.16.0 release; the co-lead's lane):**
21
- - the teams operation's JSON field `personal` → `defaultTeam` (`{team, source}`);
22
- - `E_TEAM_PERSONAL` → `E_TEAM_DEFAULT` (leaving the workspace's default team);
23
- - the broker receive label `personal` → `default`;
24
- - `settings.oats.aweb.roots.personal` is removed (enrollment is 1.16+ and uses
25
- the enrolled-root model);
26
- - readiness codes/messages lose "personal".
27
- - **aweb** renames its `personal-workspace` endpoints, auth scope, CLI help and
28
- flags, and binding file likewise (aweb's lane).
29
- - **The kernel** carries no wire name with "personal" (only prose/comments,
30
- renamed). The Desktop reads `defaultTeam`.
31
-
32
- The model below is otherwise unchanged: the default team only, by default;
33
- joining is explicit; only the soul's labels that the workspace maps.
34
-
35
- ## The model (human, 2026-09-25)
36
-
37
- - **Default: the personal team only.** Every instance is in its person's
38
- personal team for THIS workspace. A soul's `team` labels do NOT put it
39
- in those teams by default.
40
- - **Joining is explicit.** A wider team is joined by an explicit action:
41
- - at spawn, a spawn choice;
42
- - or at any point of the instance's life, one simple command, run by the
43
- human, by another agent, or by the instance itself when told to.
44
- - **Only what the soul and workspace allow.** The teams an instance MAY join
45
- are exactly its soul's labels that the workspace maps. Nothing else is
46
- offered or accepted.
47
- - **Leaving** is the same kind of command. When the workspace removes a
48
- mapping or the soul drops a label, the joined membership for it is left.
49
- - **The Desktop has controls for it:** at spawn (which eligible teams to
50
- join) and on a live instance (join/leave, and the joined vs eligible
51
- teams).
52
- - **Personal teams are per WORKSPACE.** One personal team spanning several
53
- workspaces is wrong. Until aweb ships the per-workspace get-or-create, the
54
- person's single default team is an explicitly temporary stand-in.
55
-
56
- ## Problem
57
-
58
- - A v2 soul names ONE team label (`soul.yaml` `team`, else the repository's
59
- default from `oats-membership.yaml`).
60
- - The resolver merges `workspace.messaging ⊕ byTeam[<that label>]` into one
61
- messaging payload, and applies `defaults.byTeam[<that label>].capabilities`
62
- to the soul's composition.
63
- - An instance can therefore be placed in one team only, and only at spawn.
64
- - The human's bar: a person's agents are in their personal team by default,
65
- AND in every wider team their soul belongs to, at spawn and during the
66
- instance's life, and those teams are exactly the ones the workspace defines.
67
-
68
- ## Decision
69
-
70
- 1. **Several labels.**
71
- - `soul.yaml` `team` accepts a label or a non-empty list of distinct
72
- labels: `team: dev` or `team: [dev, reviewers]`.
73
- - `oats-membership.yaml`'s repository default takes the same shape.
74
- - The FIRST label is the **primary**. A single string is a one-element
75
- list, so existing souls don't change.
76
- 2. **Composition (`defaults.byTeam[*].capabilities`).**
77
- - Applied for every label, in soul order, after `defaults.capabilities`
78
- and before the soul's own `capabilities`. The soul's own entries still
79
- win.
80
- - Two labels that give the same capability different entries is
81
- `E_TEAM_CONFLICT`, naming both labels. There's no silent
82
- last-writer-wins. Identical entries from two labels are not a
83
- conflict.
84
- 3. **Messaging payload.**
85
- - **Amended (K, co-lead ruling on the 1.14.0 review):** the messaging
86
- provider's merged settings are `base ⊕ soul ⊕ host ⊕ spawn`, and **no
87
- `byTeam[<label>]` is merged into them**, the primary's included. Each
88
- label's `base ⊕ byTeam[label]` lives only in its `teams` entry (below).
89
- So `settings.team` / `OATS_TEAM_ID` mean "the personal team, if the
90
- host, soul or spawn set one"; empty means the provider's own default
91
- (for oats.aweb, the root's active team). Reason: the instance is
92
- personal-by-default (the human's model), and the primary label is just
93
- the first eligible team. Merging its payload made the provider mint the
94
- primary identity into the mapped team, and it couldn't tell a host-set
95
- personal team from the workspace's mapped one.
96
- - New and kernel-owned: `teams`, an ordered list of
97
- `{ label, mapped: boolean, payload }`.
98
- - `payload` is `base ⊕ byTeam[label]` when the workspace maps the label.
99
- - It's `base` alone, with `mapped: false`, when the label isn't mapped.
100
- - Each entry also carries the resolved team id as `team` (null when the
101
- label isn't mapped), so a provider never digs it out of `payload`.
102
- "Personal" is the provider's to resolve; the kernel says nothing about
103
- it.
104
- - These are the **eligible** teams. Joining them is explicit (see "The
105
- model"), not automatic.
106
- - It's delivered beside the settings, in the environment (`OATS_TEAMS` JSON),
107
- never inside the provider's own settings object, so it can't collide
108
- with a provider key or its manifest's settings validation.
109
- - `teams` is present when the soul has a label; a soul with no label gets
110
- `[]`, meaning "personal only".
111
- 4. **Environment.**
112
- - `OATS_TEAM_LABEL` / `OATS_TEAM_ID` stay the primary's.
113
- - New: `OATS_TEAM_LABELS` (all labels, comma-joined, in order) and
114
- `OATS_TEAMS` (the JSON above).
115
- - New: `OATS_TEAMS_SOURCE`, which is `live` or `recorded` (decision 6). It's empty
116
- when `OATS_TEAMS` is empty (unknown).
117
- - **The environment is the only channel.** No stdin wire gains keys: the
118
- binding check's request stays exactly the released wire, because released
119
- providers (oats.aweb 1.13.1) key it strictly and refuse unknown keys with
120
- `invalid-binding`. A provider check reads the teams from the same env
121
- variables its hooks get. (Correction after #179, co-lead finding.)
122
- - Workspace identity is unchanged: `OATS_WORKSPACE_KEY` / `OATS_WORKSPACE_NAME`.
123
- - The person's identity stays the provider's (its messaging root from host
124
- settings); the kernel passes the deployment, as today.
125
- 5. **Discovery.**
126
- - A label the workspace doesn't map is a discovery **warning**
127
- (`unmapped-team-label`), not an error, so the provider can fall back to
128
- the personal team and say so.
129
- - There's one warning per unmapped label, naming its souls
130
- (`{ code, label, souls, paths, message }`), not one per soul and label.
131
- A workspace with no `messaging.byTeam` must not print a line per soul.
132
- - A label that isn't in the workspace's `teams:` list at all stays the
133
- error it is today.
134
- 6. **Live resolution for a home.**
135
- - A home's teams are **live messaging state, not frozen composition**. The
136
- modules and skills an instance got at spawn don't change under it; which
137
- teams it belongs to follows the workspace.
138
- - For home-context provider operations and the launch hook, the kernel
139
- computes `teams` from the soul's labels at the soul commit the
140
- deployment currently resolves (the lock), and the workspace's current
141
- `messaging`.
142
- - That lets the provider offer a team the workspace added as eligible,
143
- and leave one it removed, without a respawn.
144
- - The recorded spawn-time `teams` stays in `instance.json.teams` as
145
- evidence: beside `providers`, never inside that capability-keyed map.
146
- - **Live or recorded.** When the workspace can't be read now (the host is
147
- offline, or the soul is no longer listed), the kernel falls back to the
148
- recorded set and says so: `OATS_TEAMS_SOURCE=recorded`, or
149
- `teamsSource: "recorded"` in inspect.
150
- - **A provider leaves a joined team only on a `live` answer.** On
151
- `recorded` or unknown it keeps every membership and may warn
152
- (`teams-unverified`).
153
- - Reason: a team mapped after spawn and joined live is absent from the
154
- record, and an offline host must never cost an instance a membership.
155
- - **Cost.** Live teams are computed only where they're consumed:
156
- - session start/restart;
157
- - the messaging module's own home-context commands and operations;
158
- - `inspect` / `readiness --home`.
159
-
160
- The live read covers the workspace host and the soul's repo, not a full
161
- workspace discovery. Every other in-home capability command uses the
162
- record and costs what it did before.
163
- - **0.26.0 limitation:** a scheduled wake's start uses the spawn-time teams.
164
- The scheduler is synchronous; only operator starts are live.
165
- - **Retire** works from the provider's own recorded membership list,
166
- never from the live eligible set. A mapping removed after the spawn
167
- still has its membership revoked at retire.
168
- 7. **Explicit join, spawn choice, Desktop.**
169
- - The join/leave/list verbs are the provider's (oats.aweb 1.14.0), run
170
- inside a home or with `--home <abs>`, all idempotent, all with `--json`:
171
- - `oats aweb teams` answers (oats.aweb ≥1.16.0 names; see the AMENDMENT at the top)
172
- `{ defaultTeam: {team, source}, primary, eligible: [{label, team, joined}], joined: [{label, team, since, identityHome, receive}], unmapped: [label], at }`, where `receive` is `native` or `poll`, and `source` is always `setting` (the team a setting named) or `root` (the messaging root's active team);
173
- - `oats aweb join <label>[,<label>]` and
174
- `oats aweb leave <label>[,<label>]` answer the same document **plus**
175
- `actions: [{action: "join"|"leave", label, released?, receipt?}]`,
176
- one row per label acted on, in order (since oats.aweb 1.15.0; added
177
- here 2026-09-26 after the Desktop's real-provider capture found it).
178
- `released` is the provider's word for what a leave did (e.g.
179
- `released`); `receipt` is opaque provider evidence (alias release),
180
- for logs, never shown as UI. A consumer accepts `actions` on
181
- join/leave answers only, and repaints from the document itself.
182
- The workspace's default team can't be left (`E_TEAM_DEFAULT`).
183
- - The same verbs are declared as home-context operations
184
- `messaging:teams|join|leave`, so the Desktop uses `oats operation run`
185
- and needs no new kernel surface.
186
- All three are `kind: action` (the default): a `view` must answer
187
- `{documents:[…]}` (markdown/text for reading), and the teams document
188
- is structured JSON. `messaging:teams` is read-only by its own
189
- contract, which its description says. Join and leave declare one
190
- required arg, `labels` (flag `--labels`, comma-separated).
191
- - Identity model: one local identity per joined team, under the home as
192
- `.aweb-identity-<label>`. The personal-team identity is the primary one,
193
- wired to the harness. There are no global identities by default.
194
- - **Sending and receiving as a joined team (oats.aweb 1.14.0):**
195
- - Sending is complete: `aw --identity-home <identityHome> mail|chat …`,
196
- the one form the aweb inject teaches.
197
- - Receiving is by POLL: the channel plugin, the pi extension and a wake
198
- registration each listen on one identity home. The inject says to
199
- check a joined team's inbox at task boundaries, and readiness and
200
- `receive: poll` say so.
201
- - Native receive for joined teams needs one of two aweb primitives:
202
- wake/channel on several identity homes per instance home, or global
203
- instance identities with address release (one identity, many teams,
204
- one channel). This is a named gap against the "seamless" bar,
205
- tracked as an aweb ask.
206
- - Each is idempotent, and refuses a label the instance isn't eligible for
207
- (`E_TEAM_NOT_ELIGIBLE`, naming the eligible labels).
208
- - **Declared setting keys (added after #179):** the spawn preview's
209
- `modules[]` rows and `inspect`'s `capabilities[]` rows carry
210
- `declares: [<setting key>…]` (names only; feature `settings-declared`).
211
- That's how a Desktop sees that the messaging manifest declares
212
- `settings.join` without reading manifests.
213
- - `inspect --soul` on a soul whose labels conflict (`E_TEAM_CONFLICT`)
214
- refuses. The error details name the capability and both labels; no
215
- `teams` is answered, because the soul can't be spawned until the
216
- workspace resolves it.
217
- - At spawn, the kernel carries the operator's choice to the provider as a
218
- spawn provider setting (`--provider <messaging> join=<label>[,<label>]`).
219
- That needs no new kernel flag, and the spawn preview shows it.
220
- - The launch hook re-checks joined memberships against the live eligible
221
- set: it leaves what's no longer eligible (only when
222
- `OATS_TEAMS_SOURCE=live`, decision 6) and never joins on its own.
223
- - **The kernel puts `teams` (eligible, the OATS_TEAMS entries) in the
224
- spawn preview and in `inspect --home`**, so a Desktop can offer the
225
- choice before anything is minted. The Desktop reads that, plus joined memberships from the provider's inspect or
226
- operation, and drives the same verbs.
227
- - Later kernel item: `oats sync` reports the souls whose labels or
228
- mappings changed since the previous lock.
229
-
230
- ## Compatibility
231
-
232
- - A single-label soul sees byte-identical **composition** (modules, skills,
233
- injects). Its messaging **payload** changes: the mapped label's `byTeam`
234
- entry is no longer merged into the provider's settings; it's only in
235
- `OATS_TEAMS` (amendment K). With 0.26.0 + oats.aweb 1.13.1, the primary
236
- identity therefore mints into the personal (root-active) team, as the
237
- human's model wants.
238
- - oats.aweb 1.13.1 ignores `OATS_TEAMS` and keeps working, because no stdin
239
- wire changes (its binding decoder refuses unknown request keys).
240
- - oats.aweb 1.14.0 reads them.
241
- - The schema change goes into 0.26.0, the release that already breaks the
242
- file formats.
243
-
244
- ## Tests
245
-
246
- - Several labels compose in order; a conflict → `E_TEAM_CONFLICT`. A
247
- capability the soul names itself is exempt, since the soul's entry wins over
248
- every label.
249
- - A mapped primary's `byTeam` payload is absent from the provider's merged
250
- settings and present in `OATS_TEAMS[0].payload` (amendment K).
251
- - `OATS_TEAMS` shape: mapped and unmapped labels, and no label → `[]`.
252
- - Home-context `teams` follows a new workspace commit (a mapping added and
253
- removed) while the home's modules stay frozen.
254
- - Discovery warns once per unmapped label.
255
- - A home whose workspace can't be read gets the record with
256
- `OATS_TEAMS_SOURCE=recorded`; a non-messaging in-home command runs no live
257
- team read.
258
- - `teams` entries carry `team`; identical cross-label entries don't conflict.
@@ -1,241 +0,0 @@
1
- # OATS for designers: the architecture, and the why, behind the Desktop
2
-
3
- **Audience:** a product designer redesigning the OATS Desktop. You don't need to read code. After this you should be able to answer the questions a user will ask the Desktop: *what is OATS, what is my setup, where does each thing come from, and why is it that way?*
4
-
5
- **Status:** the model described here is what ships in OATS 0.27.x. Things that are planned but not shipped are marked **(planned)**.
6
-
7
- ---
8
-
9
- ## 1. What OATS is, in one paragraph
10
-
11
- OATS lets a person or a company run a **team of AI agents** (Claude, Codex or Pi sessions) that each have a durable role, their own tools and knowledge, and a place to work. The unit you design and keep is a **soul** (a role, like "release manager"). The unit that actually runs is an **instance** (a working session of that soul, with its own folder and task). Everything a soul needs (tools, instructions, knowledge, messaging) comes from **Git repositories** the organisation already has, gathered into one **workspace**. OATS never "installs" anything globally: when an instance starts, OATS copies exactly what that soul needs into the instance's own folder, and records where each piece came from.
12
-
13
- **The design promise to users:** *you can always see what an agent is made of, where every part came from, and why it's there.*
14
-
15
- ---
16
-
17
- ## 2. The five things a user must be able to picture
18
-
19
- Think of these as the nouns of the product. The Desktop's job is to make each one visible and to show how they connect.
20
-
21
- | Concept | Plain meaning | Analogy |
22
- |---|---|---|
23
- | **Workspace** | The organisation's agent setup: which repositories take part, which shared tools and versions everyone uses, and the teams. One per organisation. | The company's org chart + approved-tools list. |
24
- | **Repository (member)** | A Git repo that has **joined** the workspace. It can contribute **souls** and **capabilities**. | A department that brings its people and its tools. |
25
- | **Soul** | A durable agent role: instructions, skills, and which capabilities it uses. Lives as a folder in a member repo. | A job description. |
26
- | **Instance** | A running (or stopped) incarnation of a soul: its own folder, task, work branch, and session. You spawn, attach to and retire instances. | A person currently doing that job. |
27
- | **Capability** | A reusable bundle of skills, instructions, commands and hooks (e.g. "house style", "deploy tooling", "knowledge", "messaging"). | A tool or training the person gets. |
28
-
29
- Plus two supporting nouns:
30
-
31
- - **Package**: a *versioned* bundle of capabilities published by a repo (e.g. `oats.okf v2.1.5`). The workspace pins its version.
32
- - **Deployment**: one machine's realisation of the workspace. It's a folder on the user's computer that holds the per-machine settings, the lock, the instance folders and any repo clones they work in.
33
-
34
- ---
35
-
36
- ## 3. How a workspace is set up
37
-
38
- ### 3.1 Files, and who owns them
39
-
40
- A workspace is **declared in Git**, not configured in an app. The Desktop *reads* these and helps edit them; it doesn't hold hidden state.
41
-
42
- | File | Lives in | Shared? | Says |
43
- |---|---|---|---|
44
- | `oats-workspace.yaml` | the **host** repo (any member; often a dedicated `agents` repo) | yes, via Git | the members, the pinned packages, the teams, the defaults, the knowledge stores |
45
- | `oats-membership.yaml` | **every** member repo | yes, via Git | "I belong to workspace X" (+ an optional default team) |
46
- | `souls/<name>/soul.yaml` | a member repo | yes, via Git | this role's work mode, team(s), capabilities, and where each comes from |
47
- | `capabilities/<name>/oats.json` | a member repo | yes, via Git | the capability's manifest (what it provides, optional core-capability "layer", optional repo-owned flag) |
48
- | `oats-local.yaml` | the user's **deployment folder** | **no, per machine** | which workspace this machine runs, where clones live, host-only settings (paths, keys), souls disabled here |
49
- | `oats-lock.json` | the deployment folder | per machine (but identical wherever the same workspace commit was synced) | the exact commit + content fingerprint of every pinned package |
50
-
51
- **Design implication:** show clearly **what is shared** (Git, the same for everyone in the org) versus **what is this machine** (local settings, clones, running instances). Users get confused when the two blur.
52
-
53
- ### 3.2 Membership is a two-way handshake (and it IS the trust)
54
-
55
- A repo is a member only when **both**:
56
-
57
- 1. the workspace lists it, **and**
58
- 2. the repo's `oats-membership.yaml` points back to that workspace.
59
-
60
- One side alone isn't enough (a copied file in a fork doesn't count). OATS checks both sides over Git, with the user's own access.
61
-
62
- **Why:** whoever can push to a member repo decides what its souls and capabilities are, the same trust model as the code itself. There's no separate "approve this tool" step for members.
63
-
64
- Each member shows one of these states, and the Desktop must surface them plainly:
65
-
66
- | State | What the user should understand |
67
- |---|---|
68
- | **confirmed** | It's in. Its souls and capabilities are available. |
69
- | **not listed** | The repo points at the workspace, but the workspace doesn't list it. |
70
- | **no backlink** | The workspace lists it, but the repo hasn't joined (no membership file). |
71
- | **points elsewhere** | The repo says it belongs to a different workspace. |
72
- | **can't read** | This user can't read the repo (access, network). Nothing from it is available *for this user*. |
73
-
74
- An unconfirmed member contributes **nothing**: its souls and capabilities are invisible. This is often the answer to "why can't I see soul X?"
75
-
76
- ### 3.3 Packages: the only versioned things
77
-
78
- - **Member** capabilities and souls are always the repo's **latest** default-branch state. They're not versioned.
79
- - **Packages** are **pinned**: the workspace lists `package: version`; the lock records the exact commit + fingerprint.
80
- - **Declaring a package is the trust decision.** There's no second approval.
81
- - Official packages (`oats.framework`, `oats.okf`, `oats.aweb`, `oats.jira`, `oats.linear`, `oats.authoring`, `oats.dev`) come from a reviewed **official catalog**. Others are referenced by Git URL + tag.
82
-
83
- **Why two tiers:** your own repos move fast and you trust them (latest state), while third-party or shared tooling must not change under you (pinned + fingerprinted). A repo can be **both** a member *and* publish a package. They never merge: "from this repo" means its latest `capabilities/`; "from the package" means the pinned version.
84
-
85
- **Design implication:** every capability shown should say **where it comes from**: a member repo (latest), a package (with its pinned version), or "this soul's own repo". This is the single most important fact for a user to understand their setup.
86
-
87
- ### 3.4 Teams: labels that organise, never walls
88
-
89
- - The workspace declares team labels once (e.g. `global`, `engineering`, `marketing`).
90
- - A soul has one team or several (the first is its **primary**). A repo can set a default team for its souls.
91
- - A team label can **add default capabilities** for its souls (e.g. every `engineering` soul gets the release tooling).
92
- - A team label **never** restricts, gates or changes trust. It's organisation, plus optional defaults.
93
- - For **messaging**, each label a soul carries is a team it's *eligible* to join. By default an instance is only in the workspace's **default team**, and joining others is an explicit choice, at spawn or later.
94
-
95
- ---
96
-
97
- ## 4. How a soul gets its capabilities (composition)
98
-
99
- When you spawn an instance, OATS assembles the soul's capability list from layers, later layers winning:
100
-
101
- ```
102
- workspace defaults → team defaults (per label) → the soul's own list
103
- ```
104
-
105
- - A soul can **add** capabilities, **turn off** a default (`off`), or empty a core-capability slot (`none`).
106
- - If two of a soul's teams disagree about a capability, that's a **team conflict**, and the soul can't be spawned until the workspace fixes it. The Desktop shows the two labels.
107
- - The result is an exact, fingerprinted **resolution**. Preview shows it before anything is created; if something changed between preview and spawn, OATS refuses and asks you to preview again.
108
-
109
- **Design implication:** for any soul, the Desktop can show a **composition view**: each capability, and **why it's there** (a workspace default, a team default via label X, or the soul's own choice). The kernel reports this per core capability as `from: soul | workspace | team:<label>`.
110
-
111
- ---
112
-
113
- ## 5. The core capabilities: knowledge, messaging, tasks
114
-
115
- Most capabilities are unlimited and additive (a soul can have any number). Three are special, the **core capabilities**, and each has exactly **one slot** per soul:
116
-
117
- | Core capability | What it gives an agent | Official provider | Can be `none` |
118
- |---|---|---|---|
119
- | **Knowledge** | durable, shared memory: what the organisation has learned, decisions, lessons; the agent reads it and proposes additions | `oats.okf` | yes |
120
- | **Messaging** | an identity, a team, mail/chat with other agents and humans, being woken by messages | `oats.aweb` | yes |
121
- | **Tasks** | a tracker for assignment, status, blockers (Jira, Linear) | `oats.jira`, `oats.linear` | yes |
122
-
123
- **Why slots:** an agent should have exactly one memory, one address book and one task list, not two competing ones. Everything else is additive.
124
-
125
- Plus one **default capability** almost every soul has: **`oats.core`**, which teaches the agent how to operate inside OATS (see its teammates, spawn helpers, retire). It's a workspace default and can be turned off per soul.
126
-
127
- **Vocabulary:** say **"core capabilities"** in the UI (not "layers" or "slots"; those are internal words).
128
-
129
- ### 5.1 Knowledge, specifically
130
-
131
- - Knowledge lives in **knowledge bases**: Markdown "concepts" organised in **nodes**, usually in a Git repo like `org/knowledge`.
132
- - A soul **owns** some nodes (its responsibility) and **reads** others (its starting context).
133
- - Agents propose knowledge through **pull requests**. Nothing is accepted until merged. Agents never write accepted knowledge directly.
134
- - **(planned, oats.okf 3.0.0, in progress)** Agents consult knowledge **remotely** through commands (`index`, `cat`, `search`, `links`), with **no copy inside each agent's folder**. They're told to consult it at the start of every task and regularly while working. For the Desktop this means a soul's knowledge can be browsed live, at its accepted state, from one shared place.
135
-
136
- ### 5.2 Messaging, specifically
137
-
138
- - Each instance gets a messaging **identity** (its address).
139
- - By default it's in the workspace's **default team**. It can **join** other eligible teams (from its labels) at spawn or later, and **leave** them. The default team can't be left.
140
- - Joined teams currently **check mail between tasks**; live delivery for joined teams is **(planned)**.
141
- - A stopped agent can be **woken** by a message.
142
-
143
- ---
144
-
145
- ## 6. Instances: lifecycle and work
146
-
147
- ### 6.1 Lifecycle
148
-
149
- ```
150
- preview → spawn → (start / restart / attach) → … → retire
151
- ```
152
-
153
- - **Spawn** creates the instance folder, copies the capabilities in, records provenance, and optionally starts a session.
154
- - **Start / restart** runs the session (in tmux or Herdr), with a **harness** (Claude, Codex or Pi) and a model.
155
- - **Attach** opens the live terminal.
156
- - **Retire** preserves any unfinished work, runs each capability's cleanup (e.g. revokes the messaging identity), and removes the folder.
157
-
158
- ### 6.2 Work modes (where the agent works)
159
-
160
- | Mode | Meaning |
161
- |---|---|
162
- | **worktree** | its own branch in a clone of the soul's repo (isolated) |
163
- | **checkout** | the shared current branch (for coordinators) |
164
- | **attached** | another instance's work tree (a helper inside a parent's work) |
165
- | **directory** | an independent folder, no Git |
166
- | **workspace** | a read view across all member repos (cross-repo coordination) |
167
-
168
- ### 6.3 Relationships between instances
169
-
170
- Instances form a **hierarchy**: a **child** works for its parent, a **sibling** is a peer, a **parent** oversees. The Desktop's roster is this tree.
171
-
172
- ### 6.4 Provenance and drift: the "what is this agent made of?" answer
173
-
174
- Each instance records **exactly** what it was built from: every capability's source (repo or package), commit and fingerprint, plus the soul's own commit. A running instance **never changes under itself**.
175
-
176
- When the workspace moves on (a member pushes, a package version is bumped), existing instances show **drift**: `current`, `moved` (a newer version exists) or `missing` (no longer available). New spawns get the new state.
177
-
178
- **Design implication:** drift is **information, not an error.** Show it gently ("built from an older version of X; new spawns use the new one") with a clear path to re-spawn.
179
-
180
- ### 6.5 Terminology the UI should use
181
-
182
- - **Harness**, not "runtime" (Claude, Codex, Pi).
183
- - **Core capabilities**, not "layers".
184
- - **Soul / instance**, not "agent type / agent" (though "agent" is fine in casual copy).
185
- - **Repo-owned** capability: usable only by souls of its own repo.
186
-
187
- ---
188
-
189
- ## 7. What the Desktop is for (the principle)
190
-
191
- **The kernel is the model; the Desktop renders it and drives it.** Everything the Desktop shows comes from the `oats` CLI's JSON (status, workspace status, inspect, capabilities, spawn preview). The Desktop never keeps its own copy of the setup, never guesses, and gates features on what the installed CLI *declares*, not on version numbers.
192
-
193
- **So the design should answer, at a glance:**
194
-
195
- 1. **What is my workspace?** Its members (and their handshake state), its packages (and versions), its teams.
196
- 2. **Who are my agents?** Souls (what roles exist, grouped by team/repo) and instances (what's running, their hierarchy, their state).
197
- 3. **What is this agent made of, and why?** Its composition, with each capability's source and reason (workspace/team/soul), its core capabilities, harness and work mode.
198
- 4. **Where does it work?** Its work mode, branch, and repo; its Git state and pull requests.
199
- 5. **Who can it talk to?** Its messaging identity, the workspace's default team, eligible teams, joined teams.
200
- 6. **What does it know?** Its knowledge nodes (owned/read). **(planned)** A live browser of them.
201
- 7. **Is anything wrong?** Unconfirmed members, missing clones, team conflicts, drift, readiness problems, each with the plain cause and the fix.
202
-
203
- **The Desktop today already has** (0.27.x): a Workspace area (souls, capabilities with *workspace-owned / packages / repo-owned* sections, a **Setup** graph of *this computer → workspace → repos/packages*), soul pages and capability pages, a spawn dialog (with a Teams row), instance side panels (*Instance · Soul · Git & GitHub*), a live Teams panel, and terminals. The redesign is about making this **legible and professional**, not inventing new concepts.
204
-
205
- ---
206
-
207
- ## 8. Why the architecture is like this (the reasoning to carry into the design)
208
-
209
- - **Git is the source of truth.** Organisations already review, permission and history their repos. OATS reuses that instead of inventing an admin console. → *The Desktop shows and edits declarations; it doesn't hide settings in the app.*
210
- - **No installs, only copies with receipts.** Every agent's folder is self-contained and records its sources. → *"Where did this come from?" always has an exact answer. Surface it.*
211
- - **Members are live; packages are pinned.** Your own work moves fast; shared tooling doesn't shift under you. → *Always show a capability's source tier and version.*
212
- - **Membership is trust.** Joining a workspace is a two-sided, reviewable act in Git. → *Membership state is a first-class, visible status, not a hidden error.*
213
- - **Exactly one memory, one address book, one task list per agent.** → *The core capabilities are a distinct, fixed-shape section of every soul.*
214
- - **Teams organise; they don't restrict.** → *Don't design teams as permissions or walls.*
215
- - **Nothing changes under a running agent.** → *Drift is calm information with a re-spawn path.*
216
- - **Per-machine vs shared is explicit.** → *Clearly separate "this computer" from "the organisation's setup".*
217
-
218
- ---
219
-
220
- ## 9. Glossary
221
-
222
- - **Workspace**: the organisation's shared agent setup (one `oats-workspace.yaml`).
223
- - **Host repo**: the member repo that holds `oats-workspace.yaml`.
224
- - **Member**: a repo that completed the two-way handshake.
225
- - **Deployment**: one machine's folder that runs the workspace (`oats-local.yaml` + lock + instances).
226
- - **Soul**: a durable agent role (a folder with `soul.yaml`, `AGENTS.md`, skills).
227
- - **Instance**: a working incarnation of a soul (folder + task + session).
228
- - **Capability**: a reusable bundle (skills, instructions, commands, hooks).
229
- - **Core capability**: knowledge, messaging or tasks: one slot each per soul.
230
- - **Package**: a versioned, pinned bundle of capabilities.
231
- - **Official catalog**: the reviewed list of official packages and versions.
232
- - **Lock**: the exact commit + fingerprint of each package, per deployment.
233
- - **Team (label)**: an organising label; supplies defaults and eligible messaging teams.
234
- - **Default team**: the workspace's messaging team, which every instance is in by default.
235
- - **Harness**: what runs the agent session (Claude, Codex, Pi).
236
- - **Work mode**: where an instance works (worktree, checkout, attached, directory, workspace).
237
- - **Drift**: an instance built from an older state than the workspace's current one.
238
- - **Repo-owned capability**: usable only by souls of its own repo.
239
- - **Accepted knowledge**: knowledge merged into its base's accepted branch.
240
-
241
- **Further reading (technical):** `docs/workspaces.md`, `docs/souls-and-instances.md`, `docs/capabilities.md`, `docs/desktop-cli-api.md`, and the Desktop Phase F boundary `docs/design/2026-09-24-desktop-phase-f-boundary.md`.