@awebai/oats 0.25.0 → 0.25.2

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.
@@ -56,15 +56,15 @@ one soul and, optionally, one capability. Every soul gets `oats.core` from the
56
56
  the resulting layout).
57
57
 
58
58
  ```bash
59
- oats onboard ~/acme-workspace --workspace git:github.com/acme/agents
59
+ oats onboard ~/acme --workspace git:github.com/acme/agents # any directory — an existing one with your clones is fine
60
60
  ```
61
61
 
62
62
  ```
63
- ~/acme-workspace/ # the taught "<name>-workspace" convention
63
+ ~/acme/ # the directory you chose; these three entries are what the kernel needs
64
64
  ├── oats-local.yaml # { schemaVersion: 2, workspace: git:github.com/acme/agents }
65
65
  ├── oats-lock.json # lockfileVersion 3: commit + integrity + approval per package
66
66
  ├── agents/ # instance homes
67
- └── <member>/ # clones of the members you work IN (printed as next steps)
67
+ └── <member>/ # clones of the members you work IN — here or anywhere named in oats-local.yaml clones:
68
68
  ```
69
69
 
70
70
  Read the report it prints: every member row must be `✓↔` (confirmed) — fix
@@ -64,6 +64,20 @@ their names.
64
64
 
65
65
  ## Resolution
66
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`).**
67
81
  `configChain(context)` loads `oats-config.yaml` from closest scope outward.
68
82
  `resolveCapabilities(context, soulName)`:
69
83
 
@@ -196,14 +210,28 @@ never reconciled into committed souls.
196
210
 
197
211
  ## Acquisition and trust
198
212
 
199
- External installation copies/clones one exact artifact and writes
200
- `oats-lock.json` with source, version/commit, and SHA-256 tree integrity. An
201
- existing destination is never pulled silently. Resolution rejects changed
202
- 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.
203
231
 
204
232
  Executable package hooks, commands, and launch-environment authority are omitted
205
- until `oats trust <id>` marks the exact locked integrity approved. Bundled
206
- packages are framework-trusted.
233
+ until `oats trust <id>` (0.24) marks the exact locked integrity approved.
234
+ Bundled packages are framework-trusted.
207
235
  Packages under a scope's `owned/` subtree are config-owned. Anything under
208
236
  `installed/` requires a matching lock entry, so an acquired artifact cannot
209
237
  bypass executable trust by its directory location.
@@ -211,7 +239,7 @@ bypass executable trust by its directory location.
211
239
  Distribution packages generalize this: a package materializes each capability it
212
240
  exports into `.agents/capabilities/installed/<id>/`, each independently
213
241
  addressable and independently trusted at its own artifact integrity. There is no
214
- persistent package store. The `lockfileVersion: 2` lock records package
242
+ persistent package store. The 0.24 `lockfileVersion: 2` lock records package
215
243
  provenance (`packages`) and materialized capability identity (`capabilities`)
216
244
  separately. See `docs/design/package-engine-contract.md` for the resolver/lock
217
245
  API and error taxonomy.
@@ -100,9 +100,11 @@ secrets never belong in OATS config. See
100
100
 
101
101
  > **Removed: `oats.web`.** The browser web-panel capability was retired in
102
102
  > favor of the OATS Desktop app (`packages/desktop/`), which bundles the same
103
- > zero-dependency loopback server. If an `oats-lock.json` or
104
- > `oats-config.yaml` still names `oats.web`, remove that entry. Full
105
- > 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).
106
108
 
107
109
  ## Building an integration
108
110
 
@@ -39,17 +39,25 @@ Choose stable base IDs, stable owner IDs, nonoverlapping node paths and durable
39
39
  permissions. Confirm aliases and owners explicitly, rather than deriving them
40
40
  from an instance branch or name.
41
41
 
42
- Configure the absolute `bindings-file` for each source soul. Remove obsolete v1
43
- settings such as `record-window-turns` and `record-window-bytes`; v2 accepts only
44
- `bindings-file`, `harvest-runtime` and `harvest-model`. Provision **empty owned
45
- nodes** using `oats okf init`. Accept Git initialization through a reviewed PR
46
- before migration delivery; directory provisioning requires explicit confirmation
47
- and a genuinely non-Git location.
42
+ Configure the absolute `bindings-file` **and** `state-dir` for each source soul
43
+ — the oats.okf 2.1.x binding requires both as normalized absolute host paths
44
+ (`setting state-dir is required (absolute host path)` is a refusal, not a
45
+ default). Remove obsolete v1 settings such as `record-window-turns` and
46
+ `record-window-bytes`; v2 accepts exactly `bindings-file`, `state-dir`,
47
+ `harvest-runtime` and `harvest-model`. Under the 0.25 workspace model these live
48
+ in `oats-local.yaml` `settings.oats.okf` ([configuration.md](configuration.md));
49
+ a rebuilt deployment gets a **fresh** `state-dir`
50
+ ([rebuild-to-v2.md §7b](rebuild-to-v2.md#7b-okf-2-start-a-fresh-state-dir-do-not-re-point-the-old-one)).
51
+ Provision **empty owned nodes** using `oats okf init`. Accept Git initialization
52
+ through a reviewed PR before migration delivery; directory provisioning requires
53
+ explicit confirmation and a genuinely non-Git location.
48
54
 
49
55
  ## 3. Stage and deliver each legacy bundle
50
56
 
51
- From the durable deployment configuration context in an operator shell without
52
- inherited instance identity, selecting the source soul:
57
+ From the deployment directory (the one holding `oats-local.yaml`) in an operator
58
+ shell without inherited instance identity, selecting the source soul with
59
+ `--soul` — the kernel resolves the command exactly as `oats spawn --soul <x>`
60
+ would ([knowledge.md](knowledge.md#inspection-and-operator-commands)):
53
61
 
54
62
  ```bash
55
63
  oats okf migrate --legacy /absolute/soul/knowledge --base project --node expert --output /absolute/empty-migration-stage --soul domain-expert --json
package/docs/knowledge.md CHANGED
@@ -51,11 +51,13 @@ artifact**: npm drops the source worker's `CLAUDE.md -> AGENTS.md` symlink.
51
51
  Acquire the catalog Git payload; do not install a copied npm mirror as a local
52
52
  package or repair missing aliases in installed artifacts.
53
53
 
54
- With a released OATS >=0.23.0 kernel, acquire published OKF 2.0.0 from the
55
- intended deployment configuration context in an operator shell without inherited
56
- instance identity (an explicit `--soul` does not override an invoking instance's
57
- saved settings). The explicit Git source works before and after the v0.23.1
58
- framework catalog integration:
54
+ Under the 0.25 workspace model OKF is a **package**: pin it once in the
55
+ workspace file, let `oats sync` lock and approve it, and let every soul that
56
+ fills the knowledge slot say (or inherit) `oats.okf: { from: package }`.
57
+ Operator-level `oats okf` commands run from the deployment directory with
58
+ `--soul <name>` (an explicit `--soul` does not override an invoking instance's
59
+ saved settings — use a clean shell). The pinned version resolves through the
60
+ official catalog:
59
61
 
60
62
  ```yaml
61
63
  # oats-workspace.yaml
@@ -64,23 +66,29 @@ packages:
64
66
  defaults:
65
67
  knowledge: { oats.okf: { from: package } }
66
68
 
67
- # souls/domain-expert/soul.yaml
69
+ # souls/domain-expert/soul.yaml — nothing under knowledge: for oats.okf; the default fills the slot.
70
+ # What the soul owns/reads is souls/domain-expert/okf.json (below), not a soul.yaml payload.
71
+ # A soul-true binding setting is the one thing the payload may carry, e.g.:
68
72
  knowledge:
69
- owns: domain-expert
73
+ harvest-runtime: claude
70
74
 
71
75
  # oats-local.yaml (this machine)
72
76
  settings:
73
77
  oats.okf:
74
78
  bindings-file: /absolute/config/okf-bindings.json
79
+ state-dir: /absolute/state/okf
75
80
  ```
76
81
 
77
82
  ```bash
78
83
  oats sync # resolves v2.1.3 to a commit, asks executable approval once
79
- oats spawn domain-expert --preview --json # the exact oats.okf module (package, version, commit)
84
+ oats spawn domain-expert --preview --json # the exact oats.okf module (package, version, commit) + settings.oats.okf (the merged payload)
80
85
  ```
81
86
 
82
- Pinning activates nothing by itself: the soul's `knowledge:` payload and the
83
- machine's `settings.oats.okf` must be bindable. The lock stays exact until the
87
+ Pinning activates nothing by itself: the soul's `okf.json` must exist and the
88
+ merged payload (soul `knowledge:` ⊕ `settings.oats.okf` ⊕ `--provider`) must be
89
+ bindable — it may carry **only** the four settings below (`bindings-file`,
90
+ `state-dir`, `harvest-runtime`, `harvest-model`); `owns`/`reads`/`root` on the
91
+ soul payload are refused by 2.1.3, not read. The lock stays exact until the
84
92
  workspace bumps `packages.oats.okf`; v1 operators must plan migration before
85
93
  that bump. Executable changes come with a new version and a new approval. A
86
94
  service worker need not itself fill the knowledge slot (`knowledge: none`).
@@ -126,8 +134,10 @@ directory, not the current working directory:
126
134
  source homes/worktrees; keep the bindings file outside state and bases. Local
127
135
  Git locators must not be disposable linked worktrees. Directory lock/journal
128
136
  artifacts also must not overlap state, sources or another base.
129
- - Settings are `bindings-file`, `harvest-runtime` (`pi`, `claude`, `codex`,
130
- default `pi`), and optional `harvest-model`. Choose an installed, authenticated
137
+ - Settings are `bindings-file`, `state-dir` (both required, absolute host
138
+ paths), `harvest-runtime` (`pi`, `claude`, `codex`, default `pi`), and
139
+ optional `harvest-model` — the complete list a 2.1.3 payload may carry.
140
+ Choose an installed, authenticated
131
141
  worker runtime independently of the source; omitted models use that runtime's
132
142
  configured default. V1 record-window settings are not v2 settings.
133
143
 
@@ -157,7 +167,9 @@ bindings, owner declarations, base metadata or indexes fail required spawn rathe
157
167
  than silently bootstrapping empty knowledge.
158
168
 
159
169
  Provisioning is an explicit operator action. Prepare node-map files (the
160
- `nodes` object above, without its wrapper), then:
170
+ `nodes` object above, without its wrapper), then run from the **deployment
171
+ directory** (the one holding `oats-local.yaml`), naming the soul whose
172
+ `knowledge:` payload and `settings.oats.okf` the command should run with:
161
173
 
162
174
  ```bash
163
175
  # New directory base: refuses an existing destination.
@@ -166,6 +178,19 @@ oats okf init --base team --nodes /absolute/config/team-nodes.json --confirm --s
166
178
  oats okf init --base project --nodes /absolute/config/project-nodes.json --output /absolute/new-bundle-stage --soul domain-expert --json
167
179
  ```
168
180
 
181
+ These run **before any instance exists**. Outside an instance home the kernel
182
+ resolves `oats okf … --soul <name>` exactly as `oats spawn <name>` would
183
+ (discover → resolve → the soul's `oats.okf` module at its locked, approved
184
+ commit), fetches that module into the deployment's module store
185
+ (`<deployment>/.oats/modules/oats.okf@<commit12>/`) and dispatches to that copy
186
+ with the soul's merged payload as `OATS_SETTINGS`; `--soul` is required
187
+ (`E_BAD_ARGS` names it) unless the namespace's capability is a workspace
188
+ default. It never runs "the newest instance's copy" and never an unapproved
189
+ cache read (`E_PACKAGE_UNAPPROVED` until `oats sync` approves the version).
190
+ *0.25.0 still answers `E_CAPABILITY_INACTIVE` here (the operator-level dispatch
191
+ lands in 0.25.1); the interim is to run the module binary directly with
192
+ `OATS_SETTINGS` and `OATS_CLI_BIN` set, as the tarball smoke does.*
193
+
169
194
  Put the Git proposal at the configured root in an operator-owned checkout and
170
195
  review/merge it through a PR before spawning working sources. Existing ownership
171
196
  changes require an explicit reviewed operator change, not harvest. The standalone
@@ -189,7 +214,7 @@ Snapshots are immutable by protocol, not live mounts. For current accepted text:
189
214
  # From the source home:
190
215
  oats okf read --base project --path expert/index.md --json
191
216
  oats okf refresh --json
192
- # From the deployment context, even after source retirement:
217
+ # From the deployment directory (oats-local.yaml), even after source retirement — --soul selects the resolution:
193
218
  oats okf read --source /absolute/state/sources/UUID/source.json --base project --path expert/index.md --soul domain-expert --json
194
219
  oats okf refresh --source /absolute/state/sources/UUID/source.json --soul domain-expert --json
195
220
  ```
@@ -289,9 +314,17 @@ spawn and command exit alone are not successful learning.
289
314
 
290
315
  ## Inspection and operator commands
291
316
 
292
- Run home-local commands from that source home. For cross-source or retired-source
293
- commands, use the durable deployment context in a clean operator shell without
294
- another instance's `OATS_*`/`PI_*` identity; select the configured source soul.
317
+ Run home-local commands from that source home: inside an instance the
318
+ dispatcher resolves `okf` from the home's materialized module
319
+ (`instance.json.modules` → `<home>/.oats/modules/oats.okf/`). For cross-source
320
+ or retired-source commands, run from the **deployment directory** (the one
321
+ holding `oats-local.yaml`) in a clean operator shell without another instance's
322
+ `OATS_*`/`PI_*` identity, and select the source soul with `--soul <name>`: the
323
+ kernel resolves that soul as a spawn would and dispatches to the deployment's
324
+ copy of its `oats.okf` module with the soul's merged payload (see
325
+ [Acquire, bind and provision explicitly](#acquire-bind-and-provision-explicitly)).
326
+ No `oats-config.yaml` chain is consulted; a namespace no module of the soul
327
+ provides is `E_UNKNOWN_COMMAND`.
295
328
 
296
329
  ```bash
297
330
  # Read-only; no capture, refresh, scheduling or worker launch:
@@ -1,5 +1,15 @@
1
1
  # Migrating from OAS to OATS
2
2
 
3
+ > **0.25 status — this is a 0.22–0.24 procedure.** `oats migrate` and
4
+ > `oats trust` are **removed verbs** in the 0.25 kernel (`E_UNKNOWN_COMMAND`
5
+ > naming the replacement), and 0.25 reads none of the files this page
6
+ > converts to (`oats-config.yaml`, `oats-lock.json` v2, the `installed/` tier).
7
+ > An OAS deployment reaches 0.25 in two steps: run this page's commands with a
8
+ > **0.24.x** kernel (`npm install -g @awebai/oats@0.24`), then rebuild for the
9
+ > workspace model with [rebuild-to-v2.md](rebuild-to-v2.md) — which is a rewrite
10
+ > of three shared files, not a conversion, so an operator comfortable with the
11
+ > v2 declarations may skip straight to it and let the old files go.
12
+
3
13
  OATS is the successor to OAS. **OATS 0.22.0 was published on 2026-09-03**:
4
14
  the kernel, Pi adapter, and Desktop assets are available. The published
5
15
  kernel acquired the official OKF, aweb, authoring, and development packages
@@ -17,15 +27,15 @@ while its knowledge and messaging configuration remains unmigrated.
17
27
  > before activation/spawn. The v2 integration is [prepared](release-notes/v0.23.1.md),
18
28
  > not a claim that those dependencies or any deployment have already changed.
19
29
 
20
- ## Upgrade one scope
30
+ ## Upgrade one scope (0.24.x kernel)
21
31
 
22
32
  Finish or preserve active work before changing a daily-use deployment.
23
- Install OATS alongside the old CLI, then inspect the plan for the exact
24
- scope you intend to convert:
33
+ Install OATS **0.24.x** alongside the old CLI (the 0.25 line has no `oats
34
+ migrate`), then inspect the plan for the exact scope you intend to convert:
25
35
 
26
36
  ```bash
27
- npm install -g @awebai/oats@latest
28
- pi install npm:@awebai/oats-pi@latest
37
+ npm install -g @awebai/oats@0.24
38
+ pi install npm:@awebai/oats-pi@0.24
29
39
  oats migrate --from-oas --dry-run --dir /path/to/scope
30
40
  ```
31
41
 
@@ -39,10 +49,11 @@ oats doctor /path/to/scope
39
49
  ```
40
50
 
41
51
  Run the exact `oats trust <capability> --dir <scope>` commands printed by
42
- migration for the executable capabilities you approve. Trust does not
43
- transfer automatically. Verify the team ID and messaging membership with
44
- `oats aweb setup --dir /path/to/scope`, then exercise a real task, harvest,
45
- and retirement as described in [Run your first team](first-team.md).
52
+ migration for the executable capabilities you approve (0.24: per-artifact
53
+ trust; under 0.25 approval is per package version through `oats sync`). Trust
54
+ does not transfer automatically. Verify the team ID and messaging membership
55
+ with `oats aweb setup --dir /path/to/scope`, then exercise a real task,
56
+ harvest, and retirement as described in [Run your first team](first-team.md).
46
57
 
47
58
  For a multi-repository deployment, start with one scope. The explicit
48
59
  `--recursive --dir /path/to/workspace` form converts every discovered OAS