@awebai/oats 0.24.13 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/bin/oats.mjs +994 -2837
  2. package/docs/capabilities.md +136 -323
  3. package/docs/configuration.md +68 -533
  4. package/docs/conventions.md +51 -24
  5. package/docs/design/2026-09-16-fresh-operator-walkthrough.md +19 -14
  6. package/docs/design/2026-09-16-portable-migration-evidence.md +2 -0
  7. package/docs/design/2026-09-16-portable-onboarding.md +4 -2
  8. package/docs/design/2026-09-20-redesign-program-board.md +1 -1
  9. package/docs/design/2026-09-20-workspace-and-portable-adoption-plan.md +2 -0
  10. package/docs/design/2026-09-23-simplified-workspace-model.md +711 -0
  11. package/docs/design/2026-09-23-workspace-module-contracts.md +460 -0
  12. package/docs/design/2026-09-23-workspace-v2-implementation-plan.md +65 -0
  13. package/docs/design/README.md +20 -8
  14. package/docs/design/operations-contract.md +1 -0
  15. package/docs/design/package-engine-contract.md +1 -1
  16. package/docs/design/package-runtime-api.md +1 -1
  17. package/docs/desktop-cli-api.md +356 -5
  18. package/docs/desktop-succession.md +12 -6
  19. package/docs/desktop.md +9 -4
  20. package/docs/execution-targets.md +16 -4
  21. package/docs/first-team.md +107 -224
  22. package/docs/implementation.md +41 -11
  23. package/docs/integrations.md +50 -47
  24. package/docs/knowledge-capability-authoring.md +10 -4
  25. package/docs/knowledge-migration.md +21 -12
  26. package/docs/knowledge-reference/package-craft.md +11 -3
  27. package/docs/knowledge.md +60 -18
  28. package/docs/layers.md +3 -3
  29. package/docs/migration-from-oas.md +20 -9
  30. package/docs/oats-local.schema.json +50 -0
  31. package/docs/oats-membership.schema.json +23 -0
  32. package/docs/oats-workspace.schema.json +133 -48
  33. package/docs/official-marketplace.md +9 -6
  34. package/docs/packages.md +229 -440
  35. package/docs/rebuild-to-v2.md +347 -0
  36. package/docs/release-notes/v0.25.0.md +99 -0
  37. package/docs/release-notes/v0.25.1.md +94 -0
  38. package/docs/schedules.md +12 -6
  39. package/docs/soul.schema.json +41 -68
  40. package/docs/souls-and-instances.md +175 -108
  41. package/docs/workspace-adoption.md +70 -345
  42. package/docs/workspaces.md +436 -119
  43. package/lib/core.mjs +462 -61
  44. package/lib/instance-resolution.mjs +387 -0
  45. package/lib/materialize.mjs +580 -0
  46. package/lib/operator-dispatch.mjs +117 -0
  47. package/lib/packages.mjs +558 -1269
  48. package/lib/remote.mjs +718 -0
  49. package/lib/resolve.mjs +638 -0
  50. package/lib/schedule.mjs +90 -16
  51. package/lib/workspace.mjs +654 -0
  52. package/package.json +1 -1
  53. package/lib/portable-migration-artifacts.mjs +0 -135
  54. package/lib/portable-migration-evidence.mjs +0 -305
  55. package/lib/portable-migration-store.mjs +0 -199
  56. package/lib/portable-migration.mjs +0 -104
  57. package/lib/portable-onboarding-acceptance.mjs +0 -66
  58. package/lib/setup-expert-source.mjs +0 -100
@@ -1,263 +1,146 @@
1
1
  # Run your first OATS team
2
2
 
3
- Start with one repository and one small, real task. A soul keeps the role and
4
- curated skills; an instance gets a working session and repository view. With OKF
5
- v2, expertise lives in external owned nodes, not the soul or task branch.
6
-
7
- > This guide targets the **v0.23.1 integration of published OKF 2.0.0**, whose
8
- > published kernel prerequisite is OATS >=0.23.0. Check the matching framework
9
- > release availability before installation; see [release notes](release-notes/v0.23.1.md).
10
- > The [qualification example](first-team-demo.md) records real **v1** tasks on
11
- > earlier versions, not v2 acceptance. Existing knowledge needs
12
- > [v1 preservation and cutover](knowledge-migration.md), not fresh initialization.
13
-
14
- ## Install and choose a scope
15
-
16
- Install matching published kernel and Pi adapter releases. Have Node.js 22+, Git, tmux and an authenticated working runtime
17
- available. OKF's independent worker can use Pi, Claude or Codex; authenticate
18
- that selected runtime too. Plain-directory knowledge needs no Git/gh, although
19
- this guide's coding worktree does need Git.
3
+ > **Workspace model (0.25).** This page is the v2 first-team guide. The 0.24
4
+ > surface it used to describe (`oats-config.yaml`, `oats init` / `install` /
5
+ > `use` / `trust`, the 0.24 `oats onboard --dir` bootstrap that created a local
6
+ > `oats-setup-expert`) no longer exists; those verbs answer `E_UNKNOWN_COMMAND`
7
+ > naming their replacement. Model: [workspaces.md](workspaces.md) ·
8
+ > packages: [packages.md](packages.md) · moving a 0.24 deployment:
9
+ > [rebuild-to-v2.md](rebuild-to-v2.md) (§5 is the deployment layout this page
10
+ > creates). The [qualification example](first-team-demo.md) records real v1
11
+ > tasks on 0.23 and is not v2 acceptance.
12
+
13
+ Start with one workspace, one member repository and one small, real task. A
14
+ soul keeps the role and its curated skills; an instance gets a working session
15
+ and a repository view; every capability the instance runs is copied whole into
16
+ its home at spawn from a **member** repository (latest state, trusted by
17
+ membership) or from a **package** (a pinned version, executables approved once
18
+ per version in the lock). Nothing is installed.
19
+
20
+ ## 0. Prerequisites
21
+
22
+ Node.js 22+, Git with read access to the repositories below (your own
23
+ credential helpers; the kernel never prompts), tmux, and an authenticated
24
+ harness (Pi, Claude or Codex).
20
25
 
21
26
  ```bash
22
27
  npm install -g @awebai/oats@latest
23
- pi install npm:@awebai/oats-pi@latest
24
- node --version
25
- tmux -V
26
- oats version
27
- cd /path/to/project
28
- oats init --raw
29
- oats install git:github.com/awebai/oats-okf@v2.0.0
30
- oats list
28
+ node --version && tmux -V && oats version --json # features must list workspace-v2
31
29
  ```
32
30
 
33
- Use a repository with an initial commit for this coding-worktree example.
34
- Raw initialization writes editable configuration with integrations disabled;
35
- installation separately acquires the published OKF 2.0.0 closure and exact lock.
36
- Neither step approves hooks, authenticates a runtime or joins a team. Inspect
37
- the acquired version before continuing. An existing development template or
38
- lock may still select v1: follow explicit preservation/update/cutover instead
39
- of applying fresh initialization or carrying v1 knowledge settings into v2.
40
-
41
- For several repositories initialize their common workspace, then select the
42
- repository owning the soul with `--dir /path/to/workspace/project` for
43
- create/spawn/retire. A team roster does not select a work repository for spawn.
44
-
45
- ## Onboarding with the setup expert
46
-
47
- On **OATS 0.24.2 or later**, start in an explicit empty deployment:
48
-
49
- ```bash
50
- oats onboard --dir /absolute/new-deployment --json
51
- ```
52
-
53
- `oats onboard` ships from 0.24.2 (earlier kernels refuse it). It is a
54
- classic local bootstrap, not captured preparation or workspace enrollment. It
55
- acquires `oats.framework` from the official catalog, exact-locks its artifacts,
56
- selects only `oats.core` and `oats.setup` for the new local `oats-setup-expert`,
57
- and prints the exact next spawn command. Review and run the returned
58
- `result.next.command` when ready; it addresses this same kernel and deployment.
59
- Onboarding itself never launches a model, changes native authentication or
60
- installs capture hooks/services. **`oats setup` remains the separate record
61
- capture-setup command**, not an alias for onboarding.
62
-
63
- The expert receives `oats-operate`, `oats-souls`, `oats-config`, `oats-packages`
64
- and `oats-workspace-setup`, without duplicate legacy kernel skill copies. It has
65
- no hard knowledge/messaging dependency, so it can help select and configure those
66
- providers afterward. Catalog identity grants no executable trust: the bootstrap
67
- uses resource-only core/setup capabilities and refuses unexpected executable
68
- surfaces instead of auto-approving them.
31
+ ## 1. Declare the workspace (shared, in Git)
69
32
 
70
- An existing roster is refused unless `--force-existing` is explicit. That flag
71
- permits adding the new soul, not overwriting an existing setup expert or disabling
72
- providers for other souls. Failures report partial acquisition/creation rather
73
- than claiming atomic captured preparation. Preserve that evidence before retrying.
33
+ Three files, all committed ([rebuild-to-v2.md](rebuild-to-v2.md) §§2–4 show
34
+ each field):
74
35
 
75
- Optional `--workspace git:host/org/repository[@revision]` reads the selected
76
- repository through ordinary discovery: use its pinned `oats-setup-expert` import
77
- when present, otherwise its own advertised `souls/oats-setup-expert` edition at
78
- the observed revision. Missing or incompatible explicit sources refuse; they do
79
- not fall back to the packaged default. The copied edition's package must match
80
- the official acquisition; workspace policy, teams and provider adoption values
81
- are not silently adopted. Without this option, only the packaged definition and
82
- instruction text are used—no knowledge corpus is bundled. From 0.24.5, a
83
- `--workspace` onboarding also reads `package-catalog.json` **from the workspace
84
- repository at its observed revision** and acquires the `oats.framework` that
85
- catalog names; the kernel's bundled catalog is only the fallback (it is a
86
- snapshot at the kernel's own release and lags every framework release cut
87
- afterwards). `OATS_PACKAGE_CATALOG` still overrides both. The result reports
88
- `catalog.origin` (`workspace` | `bundled` | `override`), and an integrity
89
- refusal names the lag when the bundled entry caused it.
36
+ - `oats-workspace.yaml` (`schemaVersion: 2`) in **one** host repository: `name`,
37
+ `members: [<repo ref>, …]`, `teams:`, `packages: { oats.framework: v<x>, … }`,
38
+ `defaults:`. A member is a repo ref, never a revision.
39
+ - `oats-membership.yaml` (`{ schemaVersion: 2, workspace: <host ref>, team? }`)
40
+ in **every** member — the backlink half of the handshake. A repo listed
41
+ without a backlink is `no-backlink` and contributes nothing.
42
+ - `souls/<name>/soul.yaml` (`schemaVersion: 2`) in the member that owns the
43
+ soul: `name`, `description`, `work: worktree|checkout|directory|workspace`,
44
+ and `capabilities: { <cap>: { from: here | <repo key> | package } | off }`.
45
+ A capability is a directory `capabilities/<cap>/oats.json` in a member.
90
46
 
91
- The manual path below retains its stated older integration/version scope.
47
+ The smallest real setup is one repository that is host **and** member: it
48
+ carries the workspace file, its own `oats-membership.yaml` pointing at itself,
49
+ one soul and, optionally, one capability. Every soul gets `oats.core` from the
50
+ `oats.framework` package by default.
92
51
 
93
- ## Configure explicit knowledge and optional messaging
52
+ ## 2. Realize it on this machine — `oats onboard`
94
53
 
95
- Edit the existing entries in `oats-config.yaml`; do not append a second
96
- `capabilities` map. This example targets only the source soul for knowledge:
97
-
98
- ```yaml
99
- agent-types:
100
- developers:
101
- description: Coding experts
102
- capabilities:
103
- layers:
104
- knowledge:
105
- capability: oats.okf
106
- from: installed
107
- souls:
108
- backend-expert:
109
- enabled: true
110
- settings:
111
- bindings-file: /absolute/config/okf-bindings.json
112
- harvest-runtime: pi
113
- messaging: none
114
- tasks: none
115
- ```
116
-
117
- There is no hardcoded required harvester model in v2: omitted `harvest-model`
118
- uses the selected runtime's configured default. Choose a model explicitly if
119
- needed. Source and worker runtimes are independent.
120
-
121
- Review the acquired Git payload and approve executable surfaces:
54
+ `oats onboard` is the bootstrap: it writes a minimal `oats-local.yaml`, creates
55
+ `agents/` and runs the first `sync` ([rebuild-to-v2.md](rebuild-to-v2.md) §5 is
56
+ the resulting layout).
122
57
 
123
58
  ```bash
124
- oats trust oats.okf
59
+ oats onboard ~/acme-workspace --workspace git:github.com/acme/agents
125
60
  ```
126
61
 
127
- Use the catalog Git package, not the bundled npm mirror: npm omits the source
128
- worker's `CLAUDE.md` symlink, so the mirror is not a self-contained distribution.
129
- Acquisition alone is not activation or trust.
130
-
131
- Messaging is optional. If desired, retain/configure the template's `oats.aweb`
132
- layer, set `team.name` and any existing `team.id`, then review/trust it and run
133
- `oats aweb setup`. Follow its install, initialization and create/join instructions
134
- until it confirms membership. Join an existing team rather than duplicating it;
135
- setup's exit status alone does not establish onboarding completion. A source-only
136
- knowledge target does not require the service worker to have a messaging identity.
137
-
138
- ## Create the soul and provision an external base
139
-
140
- ```bash
141
- oats create backend-expert --type developers --repo . --work worktree --runtime pi
142
62
  ```
143
-
144
- Edit `agents/backend-expert/soul/AGENTS.md` for the role and required checks.
145
- V2 does not scaffold knowledge in the soul. For a small local first base, create
146
- `/absolute/config/okf-bindings.json`:
147
-
148
- ```json
149
- {"version":1,"stateDir":"../durable-okf-state","bases":{"team":{"id":"team-knowledge","kind":"directory","path":"../team-knowledge"}}}
63
+ ~/acme-workspace/ # the taught "<name>-workspace" convention
64
+ ├── oats-local.yaml # { schemaVersion: 2, workspace: git:github.com/acme/agents }
65
+ ├── oats-lock.json # lockfileVersion 3: commit + integrity + approval per package
66
+ ├── agents/ # instance homes
67
+ └── <member>/ # clones of the members you work IN (printed as next steps)
150
68
  ```
151
69
 
152
- Those paths resolve from `/absolute/config`, not the project. Choose durable,
153
- physical paths outside the source home/worktree and **outside every Git working
154
- tree**, including ignored directories. State, accepted bases and bindings must
155
- not overlap. Review [full placement rules](knowledge.md#bindings-document).
70
+ Read the report it prints: every member row must be `✓↔` (confirmed) — fix
71
+ `no-backlink` / `backlink-elsewhere` / `cannot-read` before going on. If it
72
+ exits `2`, a package needs executable approval: run `oats sync` in a terminal
73
+ and answer `approve <id> <version>? [y/N]`. Approval is per package version,
74
+ once, recorded in the lock; member capabilities need none. Then clone the
75
+ member you will work in beside `oats-local.yaml` (only a soul's work target
76
+ needs a clone — discovery and resolution run over the remotes).
156
77
 
157
- Create `/absolute/config/team-nodes.json`:
78
+ `--json` returns `onboardApi: 2` (`local`, `dir`, `agents`, `lock`, the full
79
+ `sync` report, `hosting`, `next.clone[]`, `next.spawn`); running it twice is
80
+ `E_ALREADY_ONBOARDED` (use `oats sync`); a mistyped ref is `E_REPO_REF`, an
81
+ unreadable one `E_REMOTE_UNREADABLE` with `details.rolledBack: true` — nothing
82
+ half-written is left behind. Exact shapes:
83
+ [desktop-cli-api.md](desktop-cli-api.md#oats-onboard-onboardapi-2).
158
84
 
159
- ```json
160
- {"backend":{"path":"backend","owner":"backend-expert-stable-id"}}
161
- ```
85
+ Host-owned provider values (absolute paths, state roots) go under `settings:` in
86
+ `oats-local.yaml` afterwards — never in the workspace file, whose schema refuses
87
+ them. Do not commit `oats-local.yaml`.
162
88
 
163
- Explicitly provision the new base, refusing any existing destination:
89
+ ## 3. Look before you spawn
164
90
 
165
91
  ```bash
166
- oats okf init --base team --nodes /absolute/config/team-nodes.json --confirm --soul backend-expert --json
92
+ oats souls # every non-private soul of every confirmed member, with origin and team
93
+ oats capabilities # member (origin: member <key> @ <commit>) and package (package <id> v<ver>) capabilities
94
+ oats workspace status # membership table, packages, approval state
95
+ oats spawn backend-expert --preview # modules[] with from/commit/changedSince, composed skill names, team
167
96
  ```
168
97
 
169
- Write `agents/backend-expert/soul/okf.json`:
98
+ The preview is where a skill-name clash between two composed capabilities
99
+ (`E_SKILL_DUPLICATE`) or an unapproved package (`E_PACKAGE_UNAPPROVED`) shows
100
+ up, before anything is created.
170
101
 
171
- ```json
172
- {"version":1,"owner":"backend-expert-stable-id","owns":["team/backend"],"reads":[]}
173
- ```
174
-
175
- For team-shared Git knowledge instead, follow [Git provisioning](knowledge.md#owner-and-base-descriptors)
176
- and review/merge its initialization PR before spawning. Git knowledge always
177
- uses PR delivery, not commits on the coding instance's branch.
178
-
179
- Review and commit soul/configuration/lock changes, generated ignore rules and
180
- the adopted template base under `.agents/config-templates/adopted/`. Keep
181
- credentials and private durable evidence out of Git. Check `oats doctor --soul
182
- backend-expert --json`. Configuration and a successful doctor do not substitute
183
- for accepted-base validation by the required spawn hook.
184
-
185
- ## Give an instance a real task
102
+ ## 4. Give an instance a real task
186
103
 
187
104
  ```bash
188
- oats spawn backend-expert --purpose first-fix --task "Fix one small issue, run the relevant checks, commit the code change, and report what changed. Read the relevant accepted knowledge indexes and capture non-obvious lessons in notes."
189
- oats status --team
105
+ oats spawn backend-expert --purpose first-fix --task "Fix one small issue, run the relevant checks, commit the code change, and report what changed."
106
+ oats status
190
107
  ```
191
108
 
192
- Choose `--runtime claude` or `codex` if preferred. Complete any native folder
193
- trust, authentication or messaging-plugin confirmations in the printed session.
194
- A created window is not proof the agent is working.
109
+ `--runtime pi|claude|codex` picks the harness; complete any native folder
110
+ trust or authentication prompt in the printed session. The instance home is
111
+ `agents/<soul>/instances/<instance>/`; `work/` is its repository view;
112
+ `.oats/modules/<cap>/` and `.agents/skills/<cap>/` are the copied capabilities;
113
+ `instance.json` records `modules` (from, commit, digest), `providers` and
114
+ `workspace`. A running instance never changes under itself — a member that
115
+ moves affects only new spawns, and `oats status` shows the drift
116
+ (`member moved since (now @ …)` / `capability no longer present`).
195
117
 
196
- The instance home is under `agents/<soul>/instances/<instance>/`; `work/` is its
197
- Git worktree. `knowledge/view.json` identifies immutable accepted snapshots.
198
- The worker reads indexes selectively, maintains state/log/notes, and never edits
199
- accepted knowledge. This is instructional, not an OS filesystem sandbox.
200
- Review its code commits through the repository's ordinary PR workflow.
118
+ Instance-specific provider values belong to the spawn:
119
+ `oats spawn <soul> --provider <cap> key=value` (repeatable; dotted keys nest),
120
+ recorded under `instance.json.providers.<cap>`.
201
121
 
202
- ## Inspect, judge and retire
122
+ ## 5. Judge and retire
203
123
 
204
- From the source home, read-only inspection shows identity-matching state/log/notes
205
- plus durable processing receipts:
206
-
207
- ```bash
208
- oats okf inspect --json
209
- ```
210
-
211
- Spawn registered one per-source command job, but **did not install a host timer**.
212
- For this first task an operator may request one manual harvest from the source
213
- home; without `--no-launch` this starts the configured model worker:
214
-
215
- ```bash
216
- oats okf harvest --json
217
- ```
218
-
219
- The worker judges durable notes **and captured record**, in its own directory
220
- execution space. It leaves live notes and soul skills untouched. Directory
221
- delivery is recoverable publication with validation and receipts. Git delivery
222
- requires a real reviewed PR and merge-visible acceptance. Inspect receipts rather
223
- than equating a worker spawn with learning. See [operator commands](knowledge.md#inspection-and-operator-commands)
224
- for scaffold-only requests, completion and retry.
225
-
226
- Source retirement need not wait for a worker to finish: it must first certify
227
- final notes/record custody. From the repository scope:
124
+ Review the instance's code through the repository's ordinary PR workflow. Then:
228
125
 
229
126
  ```bash
230
127
  oats retire backend-expert-first-fix
231
- oats status --team
232
- ```
233
-
234
- Read the retirement result. An uncertified capture retains the home for retry;
235
- never delete it to bypass recovery. Durable descriptors, evidence and runs survive
236
- successful retirement. Use `oats okf inspect --source <absolute-source.json>
237
- --soul backend-expert --json` from deployment context afterward. If messaging is
238
- active, also verify its retirement receipt and roster rather than assuming local
239
- cleanup proves identity release.
240
-
241
- For automatic future judgment, review [source jobs](schedules.md#okf-v2-source-jobs)
242
- and explicitly opt into host-timer installation. No-launch tests should never
243
- install it or enable live model launches.
244
-
245
- After provider acceptance, start a fresh instance of the same soul on a useful
246
- task. Check that it finds **and uses** the promoted lesson without the original
247
- source. That is the learning acceptance step; a no-launch reader only verifies
248
- scaffolding and references.
249
-
250
- ## Optional host-wide conversation capture
251
-
252
- Knowledge judgment and the native conversation record are separate. OKF uses
253
- source-targeted native capture through the CLI; host-wide watcher/hook setup is
254
- an additional deliberate operator action:
255
-
256
- ```bash
257
- oats setup
258
- oats capture --status
259
- oats recall "a phrase from your completed task"
128
+ oats status
260
129
  ```
261
130
 
262
- Capture respects privacy exclusions. Native turns are content-addressed; signed
263
- aweb messages retain their source signatures. See [where the turn record fits](2026-09-03-architecture-proposal.md#where-the-turn-record-fits).
131
+ Read the retirement result rather than assuming local cleanup proves release;
132
+ knowledge and messaging capabilities (packages such as `oats.okf`, `oats.aweb`)
133
+ add their own retire hooks and receipts — see [knowledge.md](knowledge.md) and
134
+ [capabilities.md](capabilities.md) once you add them to `packages:` and to the
135
+ soul's `capabilities:`.
136
+
137
+ ## The standalone case
138
+
139
+ If you can read a member repository but not its workspace host (a public member
140
+ of a privately hosted workspace — decision 26), point `oats-local.yaml` at the
141
+ member: `oats sync` and `oats spawn` then give the **standalone view** — the
142
+ repo's own souls with their `from: here` capabilities plus `oats.core`, marked
143
+ `standalone: true` in `sync --json` and `instance.json.workspace.standalone`.
144
+ A repository with no `oats-membership.yaml` is not a member and gets no such
145
+ view (`E_WORKSPACE_SCHEMA`); a network failure reading the host is
146
+ `E_REMOTE_UNREADABLE`, never a silent standalone.
@@ -26,10 +26,12 @@ own Claude configuration is deliberately left enabled.
26
26
  | `test/` | Capability resolver/composition/security lifecycle tests. |
27
27
  | `agents/` | The framework's own portable expert souls. |
28
28
 
29
- Capability discovery has one layout: each config scope's `.agents/capabilities/` split into
30
- `installed/` (acquired, locked, gitignored, restorable via bare `oats install`)
31
- and `owned/` (authored at that scope, config-owned trusted; committed where
32
- the scope is a git repo, plain scope-durable files elsewhere).
29
+ Capabilities have two sources and one destination: a member repo's
30
+ `capabilities/<name>/` (latest state, trusted by membership) or a package pinned
31
+ in the workspace's `packages:` and locked in `oats-lock.json` (v3); at spawn each
32
+ is copied whole into the instance's `.oats/modules/<name>/`. Nothing is
33
+ installed at a deployment (`lib/remote.mjs`, `lib/workspace.mjs`,
34
+ `lib/resolve.mjs`, `lib/packages.mjs`, `lib/materialize.mjs`).
33
35
 
34
36
  The live control panel is the OATS Desktop app (`packages/desktop/`): an
35
37
  Electron shell over a bundled zero-dependency localhost server that uses
@@ -62,6 +64,20 @@ their names.
62
64
 
63
65
  ## Resolution
64
66
 
67
+ **Workspace model (0.25, current).** `lib/instance-resolution.mjs#prepareInstance(dir, soul)`
68
+ loads `oats-local.yaml`, discovers the workspace over its Git remotes
69
+ (`lib/workspace.mjs#discoverWorkspace`, or the standalone view), finds the
70
+ soul among the confirmed members / external souls, and calls
71
+ `lib/resolve.mjs#resolveSoul` → an immutable Resolution: `modules[]` (each
72
+ `from: member|package` with commit and digest), `slots`, merged provider
73
+ `payloads`, `skills`, `injects`, `revision`. Capability order is
74
+ `defaults.<slot>` ⊕ `defaults.capabilities` ⊕ `defaults.byTeam[team]` ⊕
75
+ `soul.capabilities` (soul wins; `off` removes; a soul's `<slot>: none` empties
76
+ the slot). `lib/materialize.mjs` then copies every module whole into the home.
77
+ The normative contract is
78
+ [docs/design/2026-09-23-workspace-module-contracts.md](design/2026-09-23-workspace-module-contracts.md).
79
+
80
+ **Classic 0.24 (superseded; still carried for homes without `oats-local.yaml`).**
65
81
  `configChain(context)` loads `oats-config.yaml` from closest scope outward.
66
82
  `resolveCapabilities(context, soulName)`:
67
83
 
@@ -194,14 +210,28 @@ never reconciled into committed souls.
194
210
 
195
211
  ## Acquisition and trust
196
212
 
197
- External installation copies/clones one exact artifact and writes
198
- `oats-lock.json` with source, version/commit, and SHA-256 tree integrity. An
199
- existing destination is never pulled silently. Resolution rejects changed
200
- locked artifacts and unlocked installed/path packages.
213
+ **Workspace model (0.25, current).** Nothing is installed. `oats sync`
214
+ (`lib/packages.mjs#resolvePackages`) resolves every `packages:` entry of
215
+ `oats-workspace.yaml` to a commit, computes the package tree's integrity and
216
+ writes `oats-lock.json` **lockfileVersion 3** (`packages.<id>: { source, url,
217
+ path, version, commit, integrity, capabilities[], approved }`). Executable
218
+ approval is **per package version**, recorded in the lock as
219
+ `approved: { executables: sha256-…, at }` after `oats sync` shows the
220
+ executables and the operator says yes; a spawn of a soul using an unapproved
221
+ package is `E_PACKAGE_UNAPPROVED`, and 0.25.1 re-verifies the approved digest
222
+ against the package tree at the locked commit at every spawn. Member-tier
223
+ capabilities need no approval: membership is the trust (decision 2). The
224
+ verbs `oats install|trust|list|restore|use|migrate` are removed
225
+ (`E_UNKNOWN_COMMAND` naming the replacement).
226
+
227
+ **Classic 0.24 (superseded).** External installation copies/clones one exact
228
+ artifact and writes `oats-lock.json` with source, version/commit, and SHA-256
229
+ tree integrity. An existing destination is never pulled silently. Resolution
230
+ rejects changed locked artifacts and unlocked installed/path packages.
201
231
 
202
232
  Executable package hooks, commands, and launch-environment authority are omitted
203
- until `oats trust <id>` marks the exact locked integrity approved. Bundled
204
- packages are framework-trusted.
233
+ until `oats trust <id>` (0.24) marks the exact locked integrity approved.
234
+ Bundled packages are framework-trusted.
205
235
  Packages under a scope's `owned/` subtree are config-owned. Anything under
206
236
  `installed/` requires a matching lock entry, so an acquired artifact cannot
207
237
  bypass executable trust by its directory location.
@@ -209,7 +239,7 @@ bypass executable trust by its directory location.
209
239
  Distribution packages generalize this: a package materializes each capability it
210
240
  exports into `.agents/capabilities/installed/<id>/`, each independently
211
241
  addressable and independently trusted at its own artifact integrity. There is no
212
- persistent package store. The `lockfileVersion: 2` lock records package
242
+ persistent package store. The 0.24 `lockfileVersion: 2` lock records package
213
243
  provenance (`packages`) and materialized capability identity (`capabilities`)
214
244
  separately. See `docs/design/package-engine-contract.md` for the resolver/lock
215
245
  API and error taxonomy.
@@ -29,54 +29,50 @@ offers comments.
29
29
 
30
30
  ## Selecting an integration
31
31
 
32
- Configuration activates the package for the intended target; the manifest
33
- already declares the slot, so `oats use` writes the entry under
34
- `capabilities.layers.<slot>`:
32
+ The workspace supplies a default per slot; a soul may name another, or `none`.
33
+ The manifest already declares the slot, so a soul's `capabilities:` entry does
34
+ not repeat it — a capability with `layer: knowledge` fills the knowledge slot
35
+ wherever it arrives from:
35
36
 
36
37
  ```yaml
37
- agent-types:
38
- product-agents:
39
- description: Planner, developer, and reviewer souls (they declare `type: product-agents`)
40
-
38
+ # oats-workspace.yaml — one default per slot, for every soul
39
+ defaults:
40
+ knowledge: { oats.okf: { from: package } }
41
+ messaging: { oats.aweb: { from: package } }
42
+ tasks: { oats.linear: { from: package } }
43
+
44
+ # souls/planner/soul.yaml — keep the defaults, supply the soul's payloads
45
+ knowledge:
46
+ owns: planner
47
+ reads: [developer]
48
+ messaging:
49
+ channels: [product]
50
+ tasks:
51
+ team: ENG
52
+ project: Agent Platform
53
+
54
+ # souls/support-triager/soul.yaml — opt out of one slot, replace another
55
+ knowledge: none # empties the slot
41
56
  capabilities:
42
- layers:
43
- knowledge:
44
- capability: oats.okf
45
- from: installed
46
- settings:
47
- bindings-file: /absolute/config/okf-bindings.json
48
- messaging:
49
- capability: oats.aweb
50
- from: installed
51
- agent-types:
52
- product-agents:
53
- enabled: true
54
- settings:
55
- team: example-team
56
- tasks:
57
- capability: oats.linear
58
- from: installed
59
- agent-types:
60
- product-agents:
61
- enabled: true
62
- settings:
63
- team: ENG
64
- project: Agent Platform
57
+ oats.jira: { from: package } # its manifest says layer: tasks → replaces the default
65
58
  ```
66
59
 
67
- CLI equivalents:
60
+ Packages are pinned once in the workspace's `packages:`
61
+ (`oats.okf: v2.1.3`, …) and synced ([packages.md](packages.md)). Host-owned
62
+ values (absolute paths) go in `oats-local.yaml`:
68
63
 
69
- ```bash
70
- oats use oats.okf --global --settings bindings-file=/absolute/config/okf-bindings.json
71
- oats use oats.aweb --type product-agents
72
- oats use oats.linear --type product-agents
73
- oats use none --layer tasks # leave an inherited slot deliberately unfilled
64
+ ```yaml
65
+ settings:
66
+ oats.okf:
67
+ bindings-file: /absolute/config/okf-bindings.json
68
+ oats.aweb:
69
+ delivery: channel
74
70
  ```
75
71
 
76
- Every matching soul gets one implementation per slot. A non-matching soul can
77
- resolve a different one or leave a slot unfilled. `none` is a layer
78
- selection, not a policy: a soul with `messaging: none` has no address, which
79
- is different from a soul whose type restricts its reach.
72
+ Every soul gets one implementation per slot. Two layered capabilities arriving
73
+ for one slot (a default plus a soul entry, or two soul entries) is
74
+ `E_SLOT_CONFLICT`; spell `<cap>: off` to remove the one you do not want. `none`
75
+ is a slot selection, not a policy: a soul with `messaging: none` has no address.
80
76
 
81
77
  ## Bundled integrations
82
78
 
@@ -104,9 +100,11 @@ secrets never belong in OATS config. See
104
100
 
105
101
  > **Removed: `oats.web`.** The browser web-panel capability was retired in
106
102
  > favor of the OATS Desktop app (`packages/desktop/`), which bundles the same
107
- > zero-dependency loopback server. If an `oats-lock.json` or
108
- > `oats-config.yaml` still names `oats.web`, remove that entry. Full
109
- > migration steps: [desktop-succession](desktop-succession.md).
103
+ > zero-dependency loopback server. If an `oats-workspace.yaml` (`packages:`,
104
+ > `defaults.capabilities`) or a `soul.yaml` still names `oats.web`, remove that
105
+ > entry and `oats sync`; on a 0.24 classic deployment, remove it from
106
+ > `oats-lock.json` / `oats-config.yaml`. Full migration steps:
107
+ > [desktop-succession](desktop-succession.md).
110
108
 
111
109
  ## Building an integration
112
110
 
@@ -156,8 +154,12 @@ exist and match its owner. Acquisition/activation never bootstraps a knowledge
156
154
  base. If activating globally, provision each working soul first or target only
157
155
  ready sources.
158
156
 
159
- ```bash
160
- oats use oats.okf --soul domain-expert --settings bindings-file=/absolute/config/okf-bindings.json harvest-runtime=claude
157
+ ```yaml
158
+ # oats-local.yaml
159
+ settings:
160
+ oats.okf:
161
+ bindings-file: /absolute/config/okf-bindings.json
162
+ harvest-runtime: claude
161
163
  ```
162
164
 
163
165
  - `harvest-runtime: pi | claude | codex` defaults to `pi`, independently of the
@@ -197,8 +199,9 @@ that CLI cannot revoke the certificate.
197
199
 
198
200
  ## oats.aweb settings (1.10.0)
199
201
 
200
- Set with `oats use oats.aweb --settings <key>=<value>` at a scope, or per
201
- soul through the binding's `settings:` map.
202
+ Set in `oats-local.yaml` under `settings.oats.aweb.<key>` (host-owned), in the
203
+ soul's `messaging:` payload (true of every instance), or per spawn with
204
+ `oats spawn … --provider oats.aweb <key>=<value>`.
202
205
 
203
206
  - `delivery: channel | session` (default `channel`). `session` hands
204
207
  notification delivery to the host wake broker: `AWEB_DELIVERY=session` in
@@ -40,12 +40,18 @@ aliases or relax installed-artifact integrity checks.
40
40
  Select a deployment scope explicitly and acquire the published source, then
41
41
  opt in for an author soul:
42
42
 
43
- ```bash
44
- oats install git:github.com/awebai/oats@v0.23.0 --dir /path/to/scope
45
- oats use oats.knowledge-theory --soul <author-soul> --dir /path/to/scope
43
+ ```yaml
44
+ # oats-workspace.yaml
45
+ packages:
46
+ oats.framework: v1.1.3 # provides oats.core, oats.setup, oats.knowledge-theory
47
+
48
+ # souls/<author-soul>/soul.yaml
49
+ capabilities:
50
+ oats.knowledge-theory: { from: package }
46
51
  ```
47
52
 
48
- Git sources select `oats-package/` by default and lock the resolved commit.
53
+ `oats sync` resolves the version to a commit and locks it; the package is read
54
+ at `oats-package/` of its repository.
49
55
  The `oats.knowledge-theory` catalog shortcut uses that same published v0.23.0
50
56
  source. The current authoring-reference patch is package 1.0.1: once framework
51
57
  v0.23.1 is published, an explicit initial Git acquisition at that tag selects