@awebai/oats 0.25.8 → 0.26.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.
- package/README.md +8 -6
- package/bin/oats.mjs +576 -1714
- package/capabilities/oats-authoring/oats-package.json +2 -2
- package/capabilities/oats-authoring/oats.json +2 -2
- package/capabilities/oats-authoring/skills/integration-authoring/SKILL.md +46 -25
- package/capabilities/oats-authoring/skills/soul-craft/SKILL.md +13 -6
- package/capabilities/oats-aweb/bin/oats-aweb.mjs +334 -72
- package/capabilities/oats-aweb/injects/aweb.md +7 -2
- package/capabilities/oats-aweb/lib/binding-wire.mjs +107 -5
- package/capabilities/oats-aweb/lib/captured-native.mjs +1 -1
- package/capabilities/oats-aweb/lib/grant-custody.mjs +38 -0
- package/capabilities/oats-aweb/oats.json +14 -4
- package/capabilities/oats-jira/bin/oats-jira.mjs +4 -4
- package/capabilities/oats-jira/oats.json +2 -2
- package/capabilities/oats-jira/skills/jira-tasks/SKILL.md +6 -3
- package/capabilities/oats-linear/bin/oats-linear-hook.mjs +6 -4
- package/capabilities/oats-linear/oats.json +2 -2
- package/capabilities/oats-linear/skills/linear-tasks/SKILL.md +6 -0
- package/capabilities/oats-okf/bin/oats-okf.mjs +1 -1
- package/capabilities/oats-okf/lib/binding-wire.mjs +1 -1
- package/capabilities/oats-okf/lib/migration.mjs +2 -2
- package/capabilities/oats-okf/lib/sources.mjs +5 -4
- package/capabilities/oats-okf/lib/stores.mjs +40 -9
- package/capabilities/oats-okf/lib/worker.mjs +3 -3
- package/capabilities/oats-okf/oats.json +1 -1
- package/capabilities/oats-review/oats.json +3 -2
- package/docs/capabilities.md +218 -47
- package/docs/capability-manifest.schema.json +13 -4
- package/docs/configuration.md +17 -5
- package/docs/conventions.md +16 -26
- package/docs/design/2026-09-08-expert-assisted-deployment-proposal.md +1 -1
- package/docs/design/2026-09-13-knowledge-and-memory-direction.md +3 -3
- package/docs/design/2026-09-14-portable-souls-and-git-workspaces.md +2 -2
- package/docs/design/2026-09-15-portable-souls-handoff.md +2 -2
- package/docs/design/2026-09-15-portable-souls-implementation.md +1 -1
- package/docs/design/2026-09-20-redesign-program-board.md +2 -2
- package/docs/design/2026-09-23-workspace-module-contracts.md +1 -1
- package/docs/design/2026-09-23-workspace-v2-implementation-plan.md +1 -1
- package/docs/design/2026-09-24-desktop-phase-f-boundary.md +54 -10
- package/docs/design/2026-09-24-phase-d-plan.md +77 -0
- package/docs/design/2026-09-25-teams-contract.md +226 -0
- package/docs/design/README.md +3 -3
- package/docs/design/launch-configurations.md +20 -16
- package/docs/design/operations-contract.md +27 -10
- package/docs/desktop-cli-api.md +546 -264
- package/docs/desktop-instance-start.md +1 -1
- package/docs/desktop.md +7 -13
- package/docs/execution-targets.md +16 -18
- package/docs/first-team.md +14 -17
- package/docs/implementation.md +28 -59
- package/docs/integrations.md +88 -32
- package/docs/knowledge-capability-authoring.md +1 -1
- package/docs/knowledge-reference/package-craft.md +10 -8
- package/docs/knowledge-theory.md +1 -1
- package/docs/knowledge.md +10 -11
- package/docs/layers.md +16 -17
- package/docs/oats-local.schema.json +29 -1
- package/docs/oats-membership.schema.json +5 -3
- package/docs/oats-package.schema.json +2 -2
- package/docs/oats-workspace.schema.json +1 -1
- package/docs/{official-marketplace.md → official-catalog.md} +15 -16
- package/docs/packages.md +75 -52
- package/docs/release-notes/v0.22.0.md +1 -1
- package/docs/release-notes/v0.23.1.md +1 -1
- package/docs/release-notes/v0.25.9.md +23 -0
- package/docs/release-notes/v0.26.0.md +670 -0
- package/docs/schedules.md +48 -126
- package/docs/soul.schema.json +11 -4
- package/docs/souls-and-instances.md +56 -43
- package/docs/workspaces.md +80 -58
- package/injects/instance-boundary.md +1 -1
- package/injects/work-attached.md +1 -1
- package/injects/work-workspace.md +2 -2
- package/lib/{portable-files.mjs → bounded-read.mjs} +6 -6
- package/lib/{portable-values.mjs → canonical-json.mjs} +3 -12
- package/lib/capability-contract.mjs +110 -0
- package/lib/config-data.mjs +2 -2
- package/lib/core.mjs +700 -4824
- package/lib/digest.mjs +12 -0
- package/lib/instance-inspect.mjs +396 -0
- package/lib/instance-lifecycle.mjs +3 -4
- package/lib/instance-resolution.mjs +212 -26
- package/lib/instruction-composition.mjs +0 -20
- package/lib/materialize.mjs +6 -4
- package/lib/operator-dispatch.mjs +33 -13
- package/lib/packages.mjs +25 -190
- package/lib/provider-binding.mjs +4 -2
- package/lib/provider-reasons.mjs +3 -68
- package/lib/resolve.mjs +204 -68
- package/lib/schedule.mjs +97 -272
- package/lib/servers.mjs +13 -13
- package/lib/{portable-shape.mjs → shape.mjs} +4 -3
- package/lib/tree-copy.mjs +44 -0
- package/lib/workspace.mjs +125 -20
- package/package-catalog.json +7 -7
- package/package.json +1 -1
- package/skills/integration-authoring/SKILL.md +48 -40
- package/skills/oats-getting-started/SKILL.md +105 -110
- package/skills/oats-support/SKILL.md +2 -2
- package/skills/soul-craft/SKILL.md +13 -6
- package/bin/oats-pi-sdk-host.mjs +0 -17
- package/docs/2026-09-03-architecture-proposal.md +0 -642
- package/docs/artifact-approvals.schema.json +0 -7
- package/docs/captured-invocation-context.schema.json +0 -7
- package/docs/captured-resolution.schema.json +0 -7
- package/docs/design/package-engine-contract.md +0 -813
- package/docs/design/package-runtime-api.md +0 -588
- package/docs/desktop-succession.md +0 -57
- package/docs/execution-capsule.schema.json +0 -108
- package/docs/first-team-demo.md +0 -92
- package/docs/knowledge-migration.md +0 -147
- package/docs/migration-from-oas.md +0 -103
- package/docs/oats-config.schema.json +0 -172
- package/docs/oats-lock-v3.schema.json +0 -7
- package/docs/oats-lock.schema.json +0 -175
- package/docs/operating-team-migration.md +0 -470
- package/docs/portable.schema.json +0 -2512
- package/docs/provider-check-input.schema.json +0 -7
- package/docs/rebuild-to-v2.md +0 -511
- package/docs/workspace-adoption.md +0 -74
- package/injects/framework-workspace.md +0 -7
- package/injects/local-soul.md +0 -19
- package/injects/oats-portable.md +0 -20
- package/injects/oats.md +0 -11
- package/injects/portable-instance-boundary.md +0 -39
- package/injects/portable-work-directory.md +0 -29
- package/lib/artifact-approvals.mjs +0 -120
- package/lib/artifact-tree.mjs +0 -141
- package/lib/capability-artifacts.mjs +0 -179
- package/lib/capability-execution.mjs +0 -15
- package/lib/capability-inputs.mjs +0 -39
- package/lib/capability-provenance.mjs +0 -231
- package/lib/captured-action-shape.mjs +0 -21
- package/lib/captured-admission-shape.mjs +0 -20
- package/lib/captured-binding-file.mjs +0 -36
- package/lib/captured-dispatch.mjs +0 -66
- package/lib/captured-instance-index.mjs +0 -277
- package/lib/captured-invocation-context.mjs +0 -130
- package/lib/captured-launch-request.mjs +0 -66
- package/lib/captured-operation-process.mjs +0 -15
- package/lib/captured-pi-custody.mjs +0 -29
- package/lib/captured-pi-host.mjs +0 -167
- package/lib/captured-pi-outcome.mjs +0 -172
- package/lib/captured-resolutions.mjs +0 -275
- package/lib/captured-scaffold.mjs +0 -87
- package/lib/captured-selector.mjs +0 -28
- package/lib/captured-session-backend.mjs +0 -52
- package/lib/captured-source-receipt-file.mjs +0 -72
- package/lib/helper-injection-policy.mjs +0 -104
- package/lib/legacy-lock-codec.mjs +0 -106
- package/lib/manifest-settings.mjs +0 -84
- package/lib/package-closure.mjs +0 -48
- package/lib/package-materialization.mjs +0 -83
- package/lib/pi-sdk-host.mjs +0 -229
- package/lib/portable-artifacts.mjs +0 -115
- package/lib/portable-choices.mjs +0 -82
- package/lib/portable-composition.mjs +0 -136
- package/lib/portable-digest.mjs +0 -105
- package/lib/portable-identity.mjs +0 -40
- package/lib/portable-lock.mjs +0 -117
- package/lib/portable-onboarding-request.mjs +0 -49
- package/lib/portable-onboarding.mjs +0 -256
- package/lib/portable-package-preparation.mjs +0 -188
- package/lib/portable-policy.mjs +0 -44
- package/lib/portable-soul.mjs +0 -42
- package/lib/portable-state.mjs +0 -80
- package/lib/prepare-composition.mjs +0 -170
- package/lib/prepared-bindings.mjs +0 -92
- package/lib/prepared-resources.mjs +0 -127
- package/lib/provider-binding-broker.mjs +0 -65
- package/lib/provider-binding-wire.mjs +0 -116
- package/lib/readiness.mjs +0 -225
- package/lib/repository-observation.mjs +0 -226
- package/lib/resolution-shape.mjs +0 -393
- package/lib/schedule-capsule.mjs +0 -206
- package/lib/soul-constraints.mjs +0 -40
- package/lib/source-projection.mjs +0 -84
- package/lib/source-spec.mjs +0 -189
- package/lib/workspace-definition.mjs +0 -126
- package/lib/workspace-discovery.mjs +0 -146
- package/skills/oats/SKILL.md +0 -162
- package/skills/oats-config/SKILL.md +0 -164
- package/skills/oats-packages/SKILL.md +0 -184
- package/skills/oats-portable/SKILL.md +0 -115
- package/skills/oats-portable-artifacts/SKILL.md +0 -63
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://oats.dev/schemas/provider-check-input-v1.json",
|
|
4
|
-
"title": "Provider check input v1",
|
|
5
|
-
"description": "New private wire boundary; public consumer activation requires the explicit preparation/migration integration. See portable-v1.json for semantic verification requirements.",
|
|
6
|
-
"$ref": "https://oats.dev/schemas/portable-v1.json#/$defs/ProviderCheckInput"
|
|
7
|
-
}
|
package/docs/rebuild-to-v2.md
DELETED
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
# Rebuilding a 0.24.x deployment for the workspace model (0.25)
|
|
2
|
-
|
|
3
|
-
The workspace model ([workspaces.md](workspaces.md)) is a **clean v2**: no
|
|
4
|
-
converter, no dual-schema reader, no `oats migrate`. This guide is what ships
|
|
5
|
-
instead (decision 15 of `workspace-model-v2`). It is short because the new
|
|
6
|
-
surface is small: three shared files, one local file, one command.
|
|
7
|
-
|
|
8
|
-
## 0. 0.24.x keeps working
|
|
9
|
-
|
|
10
|
-
A 0.24.x kernel keeps spawning 0.24.x deployments indefinitely. Nothing forces
|
|
11
|
-
the move: install 0.25 when you are ready to rebuild, not before. A 0.25 kernel
|
|
12
|
-
reads only v2 files — a 0.24 `oats-workspace.yaml` (`schemaVersion: 1`), a
|
|
13
|
-
`soul.yaml` with `requires:`/`source:`, an `oats.yaml`, an `oats-config.yaml` or
|
|
14
|
-
a lock v1/v2 is an error **naming the schema** (`E_WORKSPACE_SCHEMA "… reads
|
|
15
|
-
schemaVersion 2 only; found 1"`, `E_LOCK_SCHEMA`), never a silent fallback.
|
|
16
|
-
Keep the 0.24 kernel installed until the last 0.24 deployment you care about is
|
|
17
|
-
rebuilt; the two do not share files.
|
|
18
|
-
|
|
19
|
-
**One thing a 0.25 kernel changes for a classic home it does launch.** Decision
|
|
20
|
-
13 ("harnesses start normally") is a property of the 0.25 *launcher*, not of the
|
|
21
|
-
v2 files: every `pi` launch a 0.25 kernel performs — `oats spawn`, `oats session
|
|
22
|
-
start|restart`, scheduled runs — starts pi with cwd = the instance home and pi's
|
|
23
|
-
own skill and context discovery intact (`--append-system-prompt <home>/AGENTS.md`,
|
|
24
|
-
no `--no-skills` / `--no-context-files` / `--no-prompt-templates` exclusion).
|
|
25
|
-
That holds for a classic 0.24 home (no `oats-local.yaml`, spawned through the
|
|
26
|
-
pre-v2 compose path that 0.25 still carries) exactly as for a module home. If you
|
|
27
|
-
relied on 0.24's ambient-skill exclusion to hide machine-level or repo-level
|
|
28
|
-
skills from an instance, that isolation is gone the moment a 0.25 kernel
|
|
29
|
-
launches it — keep the 0.24 kernel for those homes, or accept the ambient set
|
|
30
|
-
(the spawn preview lists composed skill names so a clash is visible).
|
|
31
|
-
|
|
32
|
-
## 1. Decide the one workspace
|
|
33
|
-
|
|
34
|
-
One workspace per organisation. Pick the repo that **hosts**
|
|
35
|
-
`oats-workspace.yaml` (a dedicated `agents` repo is common; any member can host
|
|
36
|
-
it). Decide the team labels you want (`global`, `engineering`, …) — labels
|
|
37
|
-
organise and may add defaults; they never gate anything.
|
|
38
|
-
|
|
39
|
-
**If any member is private, host the workspace file in a private repo that is
|
|
40
|
-
not a public member.** The workspace file names every member, so whoever can
|
|
41
|
-
read it sees the member list: a public host would publish the private repo's
|
|
42
|
-
name; hosting inside the private member hides the workspace from public
|
|
43
|
-
contributors entirely. A dedicated private repo (`<org>/workspace`) is the
|
|
44
|
-
honest shape. Public contributors who can read a public member but not the
|
|
45
|
-
host still get that member's souls through the standalone case (`from: here`
|
|
46
|
-
capabilities plus `oats.core`), so a public soul stays usable.
|
|
47
|
-
|
|
48
|
-
Two teams that need two different messaging identities (an open-source team
|
|
49
|
-
and a hosted-operations team, say) stay in ONE workspace: `team:` is a label,
|
|
50
|
-
and the provider payload is addressed by label under `messaging.byTeam` (§2).
|
|
51
|
-
Read §8b before relying on it: oats.aweb 1.12.0 mints into the `team` the
|
|
52
|
-
payload names, but the `.aw` root it mints FROM is still found by search and
|
|
53
|
-
must hold that team's membership (1.11.2 ignored `team` altogether).
|
|
54
|
-
|
|
55
|
-
## 2. Write `oats-workspace.yaml` v2 in the host repo
|
|
56
|
-
|
|
57
|
-
Start from the 0.24 file and rewrite it:
|
|
58
|
-
|
|
59
|
-
| 0.24 | v2 |
|
|
60
|
-
|---|---|
|
|
61
|
-
| `schemaVersion: 1` | `schemaVersion: 2` |
|
|
62
|
-
| `members: [{ source: git:… }]` | `members: [git:…]` — plain refs, **no** `@revision` |
|
|
63
|
-
| `imports:` of your **own** repos' souls | delete — member souls are discovered by convention |
|
|
64
|
-
| `imports:` of a **stranger's** soul (with `revision`) | `external: [{ source: git:<repo>@<full OID>, soul: <path> }]` |
|
|
65
|
-
| `teams: { private: per-human }` (the messaging payload) | `messaging: { private: per-human }`; `teams:` now declares **labels** |
|
|
66
|
-
| `defaults.knowledge: { capability, source }` | `defaults.knowledge: { <cap>: { from: package } }` (one entry, or `none`) |
|
|
67
|
-
| per-soul `stores.<x>.inherit` | `stores: { <name>: git:<repo> }` once, here |
|
|
68
|
-
| `catalog:` | delete (bare versions use the official catalog; `OATS_PACKAGE_CATALOG` overrides) |
|
|
69
|
-
| — | `packages: { <id>: <version> \| git:<repo>@<ref> }` — every version your souls used to carry in `source:` lines, **once** |
|
|
70
|
-
| — | `defaults.capabilities: { oats.core: { from: package } }` and whatever every soul should get |
|
|
71
|
-
|
|
72
|
-
```yaml
|
|
73
|
-
schemaVersion: 2
|
|
74
|
-
name: acme
|
|
75
|
-
members:
|
|
76
|
-
- git:github.com/acme/agents
|
|
77
|
-
- git:github.com/acme/platform
|
|
78
|
-
packages:
|
|
79
|
-
oats.framework: v1.1.3
|
|
80
|
-
oats.okf: v2.1.4
|
|
81
|
-
oats.aweb: v1.12.0
|
|
82
|
-
teams:
|
|
83
|
-
global: { description: Org-wide }
|
|
84
|
-
engineering: { description: Platform }
|
|
85
|
-
defaults:
|
|
86
|
-
capabilities: { oats.core: { from: package } }
|
|
87
|
-
knowledge: { oats.okf: { from: package } }
|
|
88
|
-
messaging: { oats.aweb: { from: package } }
|
|
89
|
-
tasks: none
|
|
90
|
-
stores:
|
|
91
|
-
org: git:github.com/acme/knowledge
|
|
92
|
-
messaging:
|
|
93
|
-
private: per-human
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
No absolute paths anywhere (they belong in `oats-local.yaml`). `from:` values
|
|
97
|
-
that name a repo are **canonical keys** — `github.com/acme/agents`, not
|
|
98
|
-
`git:github.com/acme/agents` and not `https://…`.
|
|
99
|
-
|
|
100
|
-
## 3. Add `oats-membership.yaml` to every member (replaces `oats.yaml`)
|
|
101
|
-
|
|
102
|
-
```yaml
|
|
103
|
-
schemaVersion: 2
|
|
104
|
-
workspace: git:github.com/acme/agents
|
|
105
|
-
team: engineering # optional default label for this repo's souls/capabilities
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Delete `oats.yaml`. Its `exports:` lists are gone: every `souls/*/soul.yaml` and
|
|
109
|
-
`capabilities/*/oats.json` is discoverable; add `private: true` to the ones that
|
|
110
|
-
should stay internal. The host repo backlinks to itself like any member.
|
|
111
|
-
|
|
112
|
-
## 3b. Move the souls: `agents/<name>/soul/` → `souls/<name>/`
|
|
113
|
-
|
|
114
|
-
In 0.24 a repo's souls lived at `agents/<name>/soul/` beside that soul's
|
|
115
|
-
instances. Under v2 discovery looks **only** at `souls/<name>/soul.yaml`; the
|
|
116
|
-
`agents/` directory belongs to the *deployment* (instance homes and, under the
|
|
117
|
-
kernel's per-commit soul cache, the fetched soul copies — see §7b) and is not
|
|
118
|
-
read as a soul source. Move every soul as a tracked rename so history follows:
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
mkdir -p souls
|
|
122
|
-
git mv agents/release-manager/soul souls/release-manager
|
|
123
|
-
# … one line per soul; then
|
|
124
|
-
git rm -r --cached agents 2>/dev/null; echo 'agents/' >> .gitignore # instances were never meant to be tracked
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
`souls/<name>/` keeps its `AGENTS.md`, `CLAUDE.md → AGENTS.md` alias, `skills/`,
|
|
128
|
-
`knowledge/` and `soul.yaml` (rewritten in §4); the directory name must equal
|
|
129
|
-
`soul.yaml#name`. Then fix whatever enumerates the old path: repo tests, scripts,
|
|
130
|
-
CI checks and any `oats.yaml`-era `exports:` tooling that globbed
|
|
131
|
-
`agents/*/soul/soul.yaml` (`git grep -n 'agents/.*/soul'` finds them) — under v2
|
|
132
|
-
they enumerate `souls/*/soul.yaml`. A soul left under `agents/` is invisible to
|
|
133
|
-
`oats souls` and to `oats spawn`; nothing warns about it.
|
|
134
|
-
|
|
135
|
-
## 4. Edit every `soul.yaml` to v2
|
|
136
|
-
|
|
137
|
-
| 0.24 | v2 |
|
|
138
|
-
|---|---|
|
|
139
|
-
| `schemaVersion: 1` | `schemaVersion: 2` |
|
|
140
|
-
| `requires.knowledge: { capability: oats.okf, source: git:…@v2.1.4#oats-package }` | `capabilities: { oats.okf: { from: package } }` — or nothing, if the workspace default already says so |
|
|
141
|
-
| `requires.capabilities.<cap>: { source: git:… }` | `<cap>: { from: package }` (published) or `<cap>: { from: here }` / `{ from: <repo key> }` (a member capability) |
|
|
142
|
-
| `source: repo:…` / `path:` | `{ from: here }` |
|
|
143
|
-
| `defaults.capabilities` | fold into `capabilities:`; use `off` to remove a workspace default |
|
|
144
|
-
| `stores.inherit` | delete (stores are declared once in the workspace) |
|
|
145
|
-
| `imports` | delete |
|
|
146
|
-
| `kind`, `type`, `repo`, `runtime`, `model`, `launch-config` | delete — model/runtime/launch config are spawn-time choices; `team:` replaces `type:` as the grouping |
|
|
147
|
-
| `knowledge:` / `messaging:` payload | keep as is (opaque provider payload); `none` empties the slot. **For `oats.okf` see the box below: the payload is the binding's SETTINGS keys only; what the soul owns/reads stays in `okf.json`** |
|
|
148
|
-
| — | `compatibility: { <cap>: ">=x.y" }` if you want a floor |
|
|
149
|
-
|
|
150
|
-
```yaml
|
|
151
|
-
schemaVersion: 2
|
|
152
|
-
name: release-manager
|
|
153
|
-
description: Cuts, verifies and announces releases.
|
|
154
|
-
work: worktree
|
|
155
|
-
team: engineering
|
|
156
|
-
capabilities:
|
|
157
|
-
acme-release-tooling: { from: here }
|
|
158
|
-
# knowledge: — nothing here for oats.okf: the workspace default fills the slot and
|
|
159
|
-
# souls/release-manager/okf.json (below) says what this soul owns and reads.
|
|
160
|
-
messaging:
|
|
161
|
-
channels: [acme-eng]
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
`name` must equal the soul's directory name; `name`, `description` and `work`
|
|
165
|
-
are required. Capabilities the repo exports live at
|
|
166
|
-
`capabilities/<name>/oats.json` — the manifest is unchanged; you may add
|
|
167
|
-
`private: true` / `team:`.
|
|
168
|
-
|
|
169
|
-
**`oats.okf` 2.1.3 reads `souls/<name>/okf.json`, not a `knowledge:` payload.**
|
|
170
|
-
Earlier drafts of this guide showed `knowledge: { owns: …, reads: … }` or
|
|
171
|
-
`knowledge: { store, root }` on the soul; **no shipped provider consumes those
|
|
172
|
-
keys**. What OKF 2.1.3 actually reads at spawn is two things:
|
|
173
|
-
|
|
174
|
-
1. **`<soul>/okf.json`** (travels with the soul, fetched into the per-commit
|
|
175
|
-
soul cache like `AGENTS.md`) — the soul's knowledge declaration, exactly
|
|
176
|
-
these keys and no others:
|
|
177
|
-
|
|
178
|
-
```json
|
|
179
|
-
{ "version": 1,
|
|
180
|
-
"owner": "release-manager",
|
|
181
|
-
"owns": ["org/release-manager"],
|
|
182
|
-
"reads": ["org/platform-engineer"] }
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
`owner` is the stable owner id (what `owners.json` pins, §7b); `owns` /
|
|
186
|
-
`reads` are `<base alias>/<node>` references into the bases the machine's
|
|
187
|
-
bindings file declares (`oats okf init` / `oats okf migrate` write it;
|
|
188
|
-
`capabilities/oats-okf/lib/config.mjs#validateDeclaration` is the
|
|
189
|
-
authority). Keep the file where 0.24 had it — it moves with the soul in
|
|
190
|
-
§3b. A soul without `okf.json` whose slot resolves to `oats.okf` fails the
|
|
191
|
-
required spawn hook (`soul has no okf.json`), by design.
|
|
192
|
-
2. **The merged payload, as `OATS_SETTINGS`** — the binding's **settings
|
|
193
|
-
keys only**, the list in `capabilities/oats-okf/oats.json#settings`:
|
|
194
|
-
`bindings-file`, `state-dir` (both required, absolute host paths →
|
|
195
|
-
`oats-local.yaml`, §5), `harvest-runtime`, `harvest-model` (optional). Any
|
|
196
|
-
other key — `owns`, `reads`, `store`, `root`, `stores` — is refused
|
|
197
|
-
(`unknown OATS_SETTINGS property`). So for `oats.okf` the soul's
|
|
198
|
-
`knowledge:` payload is normally **absent** (the workspace default
|
|
199
|
-
`defaults.knowledge: { oats.okf: { from: package } }` fills the slot) or
|
|
200
|
-
carries a soul-true binding setting such as `harvest-runtime: claude`;
|
|
201
|
-
`knowledge: none` opts the soul out.
|
|
202
|
-
|
|
203
|
-
`stores:` in the workspace file names repositories for the **workspace**; where
|
|
204
|
-
OKF's bases live inside them is a **bindings-file** concern today (`bases.<alias>`
|
|
205
|
-
with `repository` + `root`), not a soul payload key. A soul payload grammar for
|
|
206
|
-
OKF (`owns`/`reads`/`root` on `soul.yaml`) is an OKF follow-up (it lands with an
|
|
207
|
-
`oats.okf` release that declares it in its binding, and this guide will say so);
|
|
208
|
-
until then the kernel forwards the payload opaquely and OKF refuses what it does
|
|
209
|
-
not know.
|
|
210
|
-
|
|
211
|
-
**Carry `team:` on every soul, or on its repo's membership.** A soul's team is
|
|
212
|
-
`soul.yaml#team`, else `oats-membership.yaml#team`, else *unassigned*
|
|
213
|
-
(`null`). Labels never gate anything, but the kernel addresses provider payload
|
|
214
|
-
by label: an unlabelled soul receives the messaging **base** payload only —
|
|
215
|
-
`workspace.messaging` minus `byTeam`, no `byTeam.<label>` block, and no
|
|
216
|
-
`defaults.byTeam.<label>` capabilities either. If your 0.24 deployment had one
|
|
217
|
-
messaging identity per team (§1), a soul that loses its label silently lands
|
|
218
|
-
outside every team-addressed payload; nothing refuses it. Label the membership
|
|
219
|
-
when a whole repo belongs to one team, and the soul when it does not.
|
|
220
|
-
|
|
221
|
-
**Per-soul memory-harvest opt-out:** not available in OKF 2.1.3 or 2.1.4 — a
|
|
222
|
-
later OKF item. Neither `okf.json` (`version`, `owner`, `owns`, `reads`) nor the settings
|
|
223
|
-
payload (`bindings-file`, `state-dir`, `harvest-runtime`, `harvest-model`) has a
|
|
224
|
-
key that keeps a soul registered for reads while excluding it from harvest. A
|
|
225
|
-
soul that must not be harvested today says `knowledge: none` (no OKF at all for
|
|
226
|
-
that soul) or `oats.okf: off`; do not invent a key — both readers refuse unknown
|
|
227
|
-
keys.
|
|
228
|
-
|
|
229
|
-
## 5. Write `oats-local.yaml` on each machine
|
|
230
|
-
|
|
231
|
-
```
|
|
232
|
-
~/acme/ # the directory YOU choose — an existing folder with your clones is the usual case
|
|
233
|
-
├── oats-local.yaml
|
|
234
|
-
├── agents/ # instance homes — created by `oats sync` if absent (0.25.2)
|
|
235
|
-
└── platform/ # member clones, wherever you keep them (here, or named in clones:)
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
```yaml
|
|
239
|
-
schemaVersion: 2
|
|
240
|
-
workspace: git:github.com/acme/agents
|
|
241
|
-
clones: # optional: member clones that are NOT at <deployment>/<member name>
|
|
242
|
-
github.com/acme/platform: /Users/ana/src/acme-platform
|
|
243
|
-
settings: # what used to be `settings:` under capabilities.layers.* in oats-config.yaml
|
|
244
|
-
oats.okf:
|
|
245
|
-
bindings-file: /Users/ana/.oats/okf-bindings.json # required by the OKF binding: absolute host path
|
|
246
|
-
state-dir: /Users/ana/.oats/okf-state # required by the OKF binding: absolute host path; FRESH for a rebuilt deployment (§7b)
|
|
247
|
-
harvest-runtime: pi # optional: pi | claude | codex (default pi)
|
|
248
|
-
oats.aweb:
|
|
249
|
-
delivery: channel # channel (default) | session — see capabilities/oats-aweb/oats.json#settings.delivery
|
|
250
|
-
souls:
|
|
251
|
-
disabled: [data-analyst]
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
**Where the kernel looks for a member clone** (a `work: worktree | checkout`
|
|
255
|
-
soul needs one; nothing else does). In this order, first hit wins:
|
|
256
|
-
|
|
257
|
-
1. `oats spawn … --repo <abs path>` — this spawn only.
|
|
258
|
-
2. `oats-local.yaml` `clones: { <repo key>: <abs path> }` — the key is the
|
|
259
|
-
member's **canonical key** (`github.com/acme/platform`; any ref spelling you
|
|
260
|
-
write is normalised through `parseRepoRef`, so `git:github.com/acme/platform`
|
|
261
|
-
and `https://github.com/acme/platform.git` address the same entry).
|
|
262
|
-
3. The convention: `<deployment>/<member name>` — the last path segment of the
|
|
263
|
-
repo key (`platform` for `github.com/acme/platform`). One exception: a member
|
|
264
|
-
whose name is `agents` is looked for at `<deployment>/agents-repo`, because
|
|
265
|
-
`<deployment>/agents/` is the instance root (above).
|
|
266
|
-
4. None found → `E_CLONE_MISSING`, naming the three remedies. A directory that
|
|
267
|
-
*is* found but whose `origin` remote is a **different repo** →
|
|
268
|
-
`E_CLONE_MISMATCH` (the clone is not the member; nothing is spawned into it).
|
|
269
|
-
|
|
270
|
-
This order was documented before 0.25.2 but the kernel did not honour it (a
|
|
271
|
-
clone had to be `--repo`'d or sit at the convention); 0.25.2 implements it as
|
|
272
|
-
written here. If your host repo is named `agents`, clone it as
|
|
273
|
-
`<deployment>/agents-repo` or name it in `clones:`.
|
|
274
|
-
|
|
275
|
-
`settings.<cap>` is merged into that capability's payload after the soul's
|
|
276
|
-
slot payload and before `spawn --provider` (decision 14); the keys are the
|
|
277
|
-
capability's own (`oats.json#settings`). For **`oats.okf` 2.1.3** the binding
|
|
278
|
-
requires both `bindings-file` and `state-dir` as normalized absolute host
|
|
279
|
-
paths (`setting state-dir is required (absolute host path)` is a refusal, not a
|
|
280
|
-
default) and accepts `harvest-runtime` / `harvest-model`. For **`oats.aweb`**
|
|
281
|
-
the one machine-level key is `delivery`: `channel` (the native aweb channel
|
|
282
|
-
packages wake the instance; default) or `session` (delivery is external —
|
|
283
|
-
`AWEB_DELIVERY=session`, the host wake broker registers the instance once it
|
|
284
|
-
exists; requires an `aw` that ships `aw wake`). `identity.source` is also legal
|
|
285
|
-
here but see §8 for why it belongs at spawn.
|
|
286
|
-
|
|
287
|
-
Move host paths from `oats-config.yaml` `settings:` here; the `souls:` blocks of
|
|
288
|
-
`oats-config.yaml` become `--provider` flags at spawn (step 8). Delete
|
|
289
|
-
`oats-config.yaml`; it is not read. Do not commit `oats-local.yaml`.
|
|
290
|
-
(`oats onboard <dir> --workspace <repo ref>` writes a minimal `oats-local.yaml`,
|
|
291
|
-
creates `agents/` and runs the first `sync` for you; add `settings:` afterwards.
|
|
292
|
-
Its `next.clone` list names **every** member that lacks a clone at the
|
|
293
|
-
convention — the host included: the host is a member like any other, and a
|
|
294
|
-
soul that lives in it and says `work: worktree` needs its clone too. Under an
|
|
295
|
-
explicit `standalone:` header the list says so and names only that repo.)
|
|
296
|
-
|
|
297
|
-
## 6. `oats sync`
|
|
298
|
-
|
|
299
|
-
From the deployment directory:
|
|
300
|
-
|
|
301
|
-
```
|
|
302
|
-
oats sync
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
It creates `agents/` if it is absent (0.25.2; a hand-written `oats-local.yaml`
|
|
306
|
-
no longer needs a `mkdir`), confirms every member (fix any `no-backlink` /
|
|
307
|
-
`backlink-elsewhere` / `cannot-read` row before going on), resolves `packages:`
|
|
308
|
-
to commits, writes `oats-lock.json` (lockfileVersion 3) and asks for executable
|
|
309
|
-
approval once per package version. The 0.24 lock is not read; delete it
|
|
310
|
-
(`E_LOCK_SCHEMA` names it if you leave it in the way).
|
|
311
|
-
|
|
312
|
-
The legacy "You run on OATS" block is no longer composed into `AGENTS.md` when
|
|
313
|
-
`oats.core` resolves as a module (0.25.2): an instance gets **one** such block,
|
|
314
|
-
the one `oats.core`'s inject carries. If you see two, the soul resolved without
|
|
315
|
-
`oats.core` (check `oats spawn <soul> --preview`).
|
|
316
|
-
|
|
317
|
-
## 7. Approve packages
|
|
318
|
-
|
|
319
|
-
Approval is **per package version, once, in the lock** — no `oats trust`, no
|
|
320
|
-
per-capability approval, no per-operator trust list. `oats sync` on a terminal
|
|
321
|
-
prints every executable (`commands.*` and `hooks.*.command` targets of every
|
|
322
|
-
capability the package provides) and asks `approve <id> <version>? [y/N]`.
|
|
323
|
-
Declined, **Ctrl+D at the prompt**, or non-interactive → exit `2`, the lock
|
|
324
|
-
records the entry unapproved, and spawns of souls using it are refused
|
|
325
|
-
(`E_PACKAGE_UNAPPROVED`) until you run `oats sync` in a terminal and say yes.
|
|
326
|
-
Member capabilities need no approval: membership is the trust.
|
|
327
|
-
|
|
328
|
-
**Non-interactive approval (CI, scripted rebuilds):**
|
|
329
|
-
|
|
330
|
-
```bash
|
|
331
|
-
oats sync --approve oats.okf@v2.1.4 --approve oats.aweb@v1.12.0
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
`--approve <id>@<version>` is repeatable and approves **exactly** the entry the
|
|
335
|
-
resolution contains for that id and version — the executables digest is always
|
|
336
|
-
computed by `sync` over the fetched tree and recorded in the lock; you never
|
|
337
|
-
type a digest. An `--approve` that names an id or version the resolution does
|
|
338
|
-
not contain is an error, not a silent skip; an entry the flags do not cover
|
|
339
|
-
stays unapproved (exit `2`, as above).
|
|
340
|
-
|
|
341
|
-
`<version>` is the value `sync --json` reports as `approvalNeeded[].version`,
|
|
342
|
-
which is what the lock records as the package's `version`. For a **catalog**
|
|
343
|
-
package that is the published version (`oats.okf@2.1.4`). For a **git** source
|
|
344
|
-
pinned by commit (`git:github.com/awebai/oats-okf@<oid>`) it is the **full
|
|
345
|
-
commit OID**, not the `git:` reference and not a tag name — copy it from the
|
|
346
|
-
`approvalNeeded` line rather than from your workspace file.
|
|
347
|
-
|
|
348
|
-
## 7b. OKF 2: start a FRESH `state-dir` — do not re-point the old one
|
|
349
|
-
|
|
350
|
-
OKF 2 pins each knowledge **owner** to a soul by path: at source registration
|
|
351
|
-
(the `oats.okf` spawn hook) it writes `owners.json` in `state-dir` as
|
|
352
|
-
`{ <owner id>: realpath(<home>/soul) }` and refuses a later registration whose
|
|
353
|
-
owner resolves to a different path (`E_OWNER stable owner ID already identifies
|
|
354
|
-
a different soul in this state namespace`).
|
|
355
|
-
|
|
356
|
-
Under v2 that path is no longer your checkout. `oats spawn` fetches the soul
|
|
357
|
-
from its member repo at the confirmed commit into the deployment's
|
|
358
|
-
**per-commit soul cache**, `agents/<name>/souls/<commit12>/` (immutable once
|
|
359
|
-
written; `agents/<name>/soul` is a kernel-swapped pointer to the current one),
|
|
360
|
-
and the instance's `<home>/soul` links **its own commit's directory** — so the
|
|
361
|
-
realpath the hook pins is `<deployment>/agents/<name>/souls/<commit12>`, which
|
|
362
|
-
never equals the 0.24 pin (`<repo>/agents/<name>/soul`) and changes whenever the
|
|
363
|
-
member moves. Two consequences:
|
|
364
|
-
|
|
365
|
-
- **Do not reuse the 0.24 `state-dir`.** Its `owners.json` pins every owner to
|
|
366
|
-
the old path; the first v2 spawn of each soul would be refused with `E_OWNER`.
|
|
367
|
-
Give the rebuilt deployment a fresh `state-dir` (§5) and a fresh
|
|
368
|
-
`bindings-file` if the old one names the old state root. The old `state-dir`
|
|
369
|
-
is **frozen custody**: read-only history (`oats okf inspect --source
|
|
370
|
-
<old-state>/sources/<id>/source.json …` still works against it), never edited,
|
|
371
|
-
never re-pointed at the new soul path. Accepted knowledge is not affected —
|
|
372
|
-
it lives in the bases, not in `state-dir`.
|
|
373
|
-
- **The owner pin is per commit.** OKF 2.1.3 records the realpath at first
|
|
374
|
-
registration and the kernel keeps that commit directory for as long as any
|
|
375
|
-
instance links it, so a running instance's pin stays valid; a *later* spawn of
|
|
376
|
-
the same soul at a newer member commit links a different directory and
|
|
377
|
-
registers under the same owner id → `E_OWNER` again. Until OKF re-bases the
|
|
378
|
-
pin on the owner identity rather than the path (an OKF 2.1.4 item), the
|
|
379
|
-
practical rule is: one `state-dir` per (deployment, soul commit) is safe;
|
|
380
|
-
moving a member that owns knowledge means a fresh `state-dir` for the new
|
|
381
|
-
commit's spawns (the previous one becomes frozen custody, as above). Plan
|
|
382
|
-
knowledge-owning souls' member commits deliberately.
|
|
383
|
-
|
|
384
|
-
## 8. Re-take a retained messaging seat with `spawn --provider`
|
|
385
|
-
|
|
386
|
-
In 0.24, an instance-specific messaging identity (a retained seat) was pinned in
|
|
387
|
-
`oats-config.yaml` under `souls:`. That home is gone; the fact belongs to the
|
|
388
|
-
**spawn**:
|
|
389
|
-
|
|
390
|
-
```bash
|
|
391
|
-
oats spawn release-manager --purpose seat --provider oats.aweb identity.source=/abs/path/to/retained/.aw
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
`--provider <cap> key=value` is repeatable; dotted keys nest. The payload is
|
|
395
|
-
merged after the soul's `messaging:` and the machine's `settings.oats.aweb`, and
|
|
396
|
-
recorded in `instance.json.providers.oats.aweb`, so exactly one instance holds
|
|
397
|
-
the seat while other instances of the soul mint fresh identities.
|
|
398
|
-
|
|
399
|
-
**The value is the path itself.** `oats.aweb` reads `identity.source` as the
|
|
400
|
-
absolute path of the `.aw` directory to retain (it must hold `signing.key`); the
|
|
401
|
-
kernel does not resolve symbolic seat names. Because it is an absolute path it is
|
|
402
|
-
a fact about ONE machine, so its other legal home is `oats-local.yaml`
|
|
403
|
-
(`settings.oats.aweb.identity.source: /abs/path`) — never the workspace file
|
|
404
|
-
(absolute paths are refused there, decision 14). Prefer the spawn form: a
|
|
405
|
-
machine-level setting would give the seat to EVERY instance of every messaging
|
|
406
|
-
soul on that machine, and a seat can be held once. The Desktop's
|
|
407
|
-
confirmed apply carries the same map.
|
|
408
|
-
|
|
409
|
-
## 8b. Where the team `.aw` lives now, and what `byTeam` does today
|
|
410
|
-
|
|
411
|
-
A freshly minted identity (every spawn without `identity.source`) needs an
|
|
412
|
-
**initialised aweb root**: a directory holding `.aw` with a team membership to
|
|
413
|
-
mint into. oats.aweb's spawn hook (1.11.2 and 1.12.0 alike) looks for `.aw` among these, first hit
|
|
414
|
-
wins: the declared team scope (`OATS_TEAM_SCOPE`, from the removed
|
|
415
|
-
`oats-config.yaml` `team:` block — **empty under v2**), the instance home, the
|
|
416
|
-
git repo containing the home, the resolution context (the soul's work repo) and
|
|
417
|
-
the git repo containing it, and the workspace root (`OATS_WORKSPACE`, which
|
|
418
|
-
under v2 is the **deployment directory** — the one holding `oats-local.yaml`).
|
|
419
|
-
None of these is the 0.24 team root you initialised with `oats aweb setup`, so
|
|
420
|
-
a rebuilt deployment mints nothing until you put `.aw` where the hook looks:
|
|
421
|
-
|
|
422
|
-
- **at the deployment directory** — `<deployment>/.aw`: one team for every
|
|
423
|
-
messaging soul spawned here; or
|
|
424
|
-
- **inside a member clone** (gitignored — add `.aw/` to the clone's
|
|
425
|
-
`.gitignore`; never commit `signing.key`): `<clone>/.aw` is found through the
|
|
426
|
-
soul's work repo, so souls whose `work:` targets *that* member mint into
|
|
427
|
-
*that* team.
|
|
428
|
-
|
|
429
|
-
`cp -R <old team root>/.aw <deployment>/.aw` (or into the clone) carries the
|
|
430
|
-
existing memberships over; `aw team list` from that directory shows the active
|
|
431
|
-
team. A `.aw` at your user home or above the deployment is **not** found on
|
|
432
|
-
purpose (a `.aw` there would be a different team; minting into it would be a
|
|
433
|
-
silent cross-team leak).
|
|
434
|
-
|
|
435
|
-
**Two teams, two identities — what actually decides the team in 1.11.2.** The
|
|
436
|
-
hook resolves the target team as: `OATS_TEAM_ID` / `OATS_TEAM_NAME` from the
|
|
437
|
-
removed `oats-config.yaml` `team:` block (empty under v2), else **the active
|
|
438
|
-
team at the `.aw` root it found**. It **does not read a `team` key from its
|
|
439
|
-
payload** (`OATS_SETTINGS`): the only payload keys 1.11.2 acts on are
|
|
440
|
-
`delivery` and `identity.source`/`identity.takeOver`. Consequently
|
|
441
|
-
`messaging.byTeam.<label>: { team: aweb:… }` is **kernel-merged and
|
|
442
|
-
delivered, but a NO-OP for oats.aweb 1.11.2** — the kernel does its part
|
|
443
|
-
(`spawn --preview` shows the merged `settings.oats.aweb` with the label's
|
|
444
|
-
`team`, and `instance.json.providers.oats.aweb` records it); the provider
|
|
445
|
-
ignores it until an oats.aweb release reads `team` from the payload. Until then
|
|
446
|
-
the only way to get per-label minting is **per-repo placement**: give each
|
|
447
|
-
team's member clone its own `.aw` whose active team is that team’s, and make
|
|
448
|
-
sure the souls of that team say `work: worktree | checkout` **on that repo**.
|
|
449
|
-
A soul with `work: directory | workspace` has no member clone as context and
|
|
450
|
-
falls through to `<deployment>/.aw` — one team only. Keep `byTeam` in the
|
|
451
|
-
workspace file anyway: it is the declared intent, the kernel honours it, and
|
|
452
|
-
the next oats.aweb picks it up without a workspace edit.
|
|
453
|
-
|
|
454
|
-
## 9. Spawn, and check drift
|
|
455
|
-
|
|
456
|
-
```bash
|
|
457
|
-
oats souls # every non-private soul of every confirmed member, with origin and team
|
|
458
|
-
oats capabilities # every capability, member (origin: member <key> @ <commit>) or package (package <id> v<ver>)
|
|
459
|
-
oats spawn <soul> --preview # modules[] with from/commit/changedSince, team, resolution revision,
|
|
460
|
-
# providers (the --provider map as given) and settings.<cap> (the merged payload each provider receives)
|
|
461
|
-
oats spawn <soul> --purpose x
|
|
462
|
-
oats status # per instance: soul: <name> from <member> @ <c7> [member moved since …]
|
|
463
|
-
# modules … [member moved since (now @ …)] / [capability no longer present]
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
`--preview` (0.25.2) prints `providers` — exactly the `--provider <cap> k=v`
|
|
467
|
-
map you gave — and `settings.<cap>` — the **merged** payload the provider's
|
|
468
|
-
binding will receive (`workspace.messaging` base ⊕ `byTeam[team]` ⊕ soul slot
|
|
469
|
-
payload ⊕ `oats-local.yaml settings.<cap>` ⊕ `--provider`), so you can see
|
|
470
|
-
before creating anything that `state-dir` is the fresh one (§7b) and that the
|
|
471
|
-
team block reached the payload (§8b). `oats status` (0.25.2) shows drift for
|
|
472
|
-
the **soul source** as well as for modules: `soul: <name> from <member> @ <c7>`
|
|
473
|
-
with `[member moved since …]` when the member's default branch has moved past
|
|
474
|
-
the commit the instance was spawned from; `--json` carries it as
|
|
475
|
-
`instances[].soul { repoKey, commit, current, status }`. A moved soul is
|
|
476
|
-
information, not a fault — the running instance keeps its own commit (§7b);
|
|
477
|
-
re-spawn when you want the new one.
|
|
478
|
-
|
|
479
|
-
**Work modes and clones.** `work: worktree | checkout` needs the member clone
|
|
480
|
-
(§5 order); `work: directory` needs nothing; `work: workspace` (a coordination
|
|
481
|
-
soul) links `./work` to the **deployment directory** — the one holding
|
|
482
|
-
`oats-local.yaml`, with `agents/` and whatever clones sit beside it — read-only
|
|
483
|
-
across members, no branch (0.25.1). Such a soul finds a member whose clone is
|
|
484
|
-
elsewhere through `oats-local.yaml` `clones:`.
|
|
485
|
-
|
|
486
|
-
## What disappears
|
|
487
|
-
|
|
488
|
-
| Gone | Replaced by |
|
|
489
|
-
|---|---|
|
|
490
|
-
| `oats-config.yaml` (and the laptop/workspace/repo config chain, `agent-types`, `capabilities.layers`/`additive`, `souls:`, adopted config templates) | `oats-workspace.yaml` defaults + `soul.yaml` `capabilities:`; `oats-local.yaml` for host settings; `spawn --provider` for per-instance facts |
|
|
491
|
-
| `oats.yaml` | `oats-membership.yaml` |
|
|
492
|
-
| `agents/<name>/soul/` as the tracked soul source | `souls/<name>/` (tracked); `agents/` is deployment state — instance homes and the kernel's per-commit soul cache `agents/<name>/souls/<commit12>/` |
|
|
493
|
-
| `.agents/capabilities/installed/` and `owned/` | nothing is installed; `<instance>/.oats/modules/<cap>/` per instance; member capabilities under `<repo>/capabilities/` |
|
|
494
|
-
| `oats init`, `oats use`, `oats install`, `oats restore`, `oats trust`, `oats list`, `oats catalog`, `oats remove`, `oats migrate`, `oats config` | `oats sync`, `oats package add \| remove`, `oats workspace status`, `oats capabilities`, `oats souls` — each removed verb answers `E_UNKNOWN_COMMAND` naming its replacement |
|
|
495
|
-
| lock v1 / v2 | lock v3 (`packages` only, with `url`, `capabilities`, `approved`) |
|
|
496
|
-
| per-soul `source: git:…@v#…`, `repo:`, `path:` | `from: here \| <repo key> \| package` + `packages:` in the workspace |
|
|
497
|
-
| `imports:` of member souls, `exports:` lists | discovery by convention; `private: true` |
|
|
498
|
-
| `stores.<x>.inherit` | `stores:` in the workspace |
|
|
499
|
-
| `teams:` as the messaging payload | `messaging:`; `teams:` are labels |
|
|
500
|
-
| `@revision` on members | none — members are latest; frozen content is a package |
|
|
501
|
-
| ambient-skill exclusion at launch | the harness starts normally; capability skills are copied to `.agents/skills/<cap>/` |
|
|
502
|
-
|
|
503
|
-
## What is kept
|
|
504
|
-
|
|
505
|
-
Kernel-neutral provider payloads and the `binding` contract; per-version
|
|
506
|
-
executable approval (now in the lock); spawn preview / confirmed apply
|
|
507
|
-
(`decision.revision`, now binding the resolution revision) and idempotency;
|
|
508
|
-
retirement and retention; the official catalog; the canonical-plus-alias
|
|
509
|
-
instance construction (`CLAUDE.md → AGENTS.md`, `.claude/skills →
|
|
510
|
-
../.agents/skills`); every published Desktop CLI contract, extended as described
|
|
511
|
-
in [desktop-cli-api.md](desktop-cli-api.md#workspace-model-workspaceapi-2).
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# Adopt the OATS development workspace
|
|
2
|
-
|
|
3
|
-
> **Superseded (workspace model, 0.25).** The 0.24 narrative this page carried
|
|
4
|
-
> — `oats.yaml` exports, `imports:` of pinned source editions, "classic local
|
|
5
|
-
> bootstrap" with `oats onboard --dir`, source-edition inspection and
|
|
6
|
-
> `oats prepare` pilots — is history: none of those files or verbs exist under
|
|
7
|
-
> the workspace model (decision 5 of `workspace-model-v2`: no migration, v1
|
|
8
|
-
> declaration files are schema errors). What replaces it is short and is
|
|
9
|
-
> written once: **[rebuild-to-v2.md](rebuild-to-v2.md)** (§5 for the
|
|
10
|
-
> deployment layout `oats onboard` creates) and [workspaces.md](workspaces.md)
|
|
11
|
-
> for the model. This page only says what the framework's own workspace looks
|
|
12
|
-
> like under v2 and how to join it.
|
|
13
|
-
|
|
14
|
-
## The framework's own workspace (decisions 18–21)
|
|
15
|
-
|
|
16
|
-
Decision 18 (W9) converts every repository of the OATS organisation to a v2
|
|
17
|
-
member: `oats-membership.yaml` naming the host, v2 `souls/*/soul.yaml`, and
|
|
18
|
-
`capabilities/*/oats.json` for what it exports at latest state. The `oats`
|
|
19
|
-
repository hosts `oats-workspace.yaml` and the official
|
|
20
|
-
`package-catalog.json`. Until that conversion has landed on `main`, the
|
|
21
|
-
repository's checked-in `oats-workspace.yaml` is still `schemaVersion: 1` and a
|
|
22
|
-
0.25 kernel refuses it by name (`E_WORKSPACE_SCHEMA`) — the commands below
|
|
23
|
-
describe the target, not a workspace you can join today.
|
|
24
|
-
|
|
25
|
-
A framework repository is a **member and a package publisher at once**, and the
|
|
26
|
-
two roles never collapse: `oats-okf`, `oats-aweb`, `oats-jira`, `oats-linear`,
|
|
27
|
-
`oats-authoring`, `oats-dev` are members (their `souls/` — `okf-expert`,
|
|
28
|
-
`aweb-expert`, … — are discoverable at latest state, team `global`) **and**
|
|
29
|
-
their `oats-package/` is consumed only as a package: `from: package`, pinned
|
|
30
|
-
in the workspace's `packages:`, locked and approved per version. The framework's
|
|
31
|
-
own souls therefore say `oats.okf: { from: package }` even though `oats-okf` is
|
|
32
|
-
a member. A bare version in `packages:` (`oats.okf: v2.1.4`) resolves through
|
|
33
|
-
the catalog; a package outside it is written `git:<repo>@<ref>`.
|
|
34
|
-
|
|
35
|
-
## Join it on your machine
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
oats onboard ~/oats-workspace --workspace git:github.com/awebai/oats
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
This writes `oats-local.yaml`, creates `agents/`, runs the first `sync`
|
|
42
|
-
(membership table, `packages:` resolved into `oats-lock.json`, approval asked
|
|
43
|
-
once per package version — exit `2` until approved in a terminal), and prints
|
|
44
|
-
which members to clone beside it. Read `oats souls` / `oats capabilities`,
|
|
45
|
-
then `oats spawn oats-setup-expert` for the guided rest. Exact shapes and
|
|
46
|
-
errors (`E_ALREADY_ONBOARDED`, `E_REPO_REF`, `details.rolledBack`):
|
|
47
|
-
[desktop-cli-api.md](desktop-cli-api.md#oats-onboard-onboardapi-2).
|
|
48
|
-
|
|
49
|
-
Shared vs local is now one rule: **what is true of the workspace lives in the
|
|
50
|
-
host repo and the members (Git); what is true of this machine lives in
|
|
51
|
-
`oats-local.yaml` (`settings:`, `clones:`, `souls.disabled`, never committed);
|
|
52
|
-
what is true of one instance is given at spawn (`--provider <cap> k=v`)**. No
|
|
53
|
-
machine path, credential, private team identifier or store locator belongs in
|
|
54
|
-
the workspace file — its schema refuses absolute paths.
|
|
55
|
-
|
|
56
|
-
## Public contributors: the standalone view
|
|
57
|
-
|
|
58
|
-
The workspace file names every member, so a mixed public/private organisation
|
|
59
|
-
hosts it in a private repo that is not a public member (decision 26). A
|
|
60
|
-
contributor who can read a public member but not the host points
|
|
61
|
-
`oats-local.yaml` at the member and gets the **standalone view**: the member's
|
|
62
|
-
own souls with `from: here` capabilities plus `oats.core` (decision 25), marked
|
|
63
|
-
`standalone: true` in `oats sync --json` and in
|
|
64
|
-
`instance.json.workspace.standalone`. The view exists only for a repo that *is*
|
|
65
|
-
a member (it has `oats-membership.yaml`) whose host is unreadable for
|
|
66
|
-
access reasons; a repo without a backlink is `E_WORKSPACE_SCHEMA`, and a network
|
|
67
|
-
or timeout failure reading the host is `E_REMOTE_UNREADABLE`, never a silent
|
|
68
|
-
fallback.
|
|
69
|
-
|
|
70
|
-
## History
|
|
71
|
-
|
|
72
|
-
The 0.24 adoption record (PR23 and the portable-souls program) is kept in
|
|
73
|
-
[design/2026-09-20-redesign-program-board.md](design/2026-09-20-redesign-program-board.md)
|
|
74
|
-
and the superseded design notes under [design/](design/README.md).
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
## OATS framework workspace (sticky)
|
|
2
|
-
|
|
3
|
-
You are an OATS framework agent. The framework's generic skills govern your work:
|
|
4
|
-
**okf** (knowledge bundles), **memory-harvest** (promotion judgment),
|
|
5
|
-
**skill-craft** and **soul-craft** (creating/maintaining skills and souls).
|
|
6
|
-
The implementation you steward lives in this repo (`extension/`, `skills/`, `injects/`), installed via `pi install`.
|
|
7
|
-
Changes to the framework are proposed to the human before landing.
|
package/injects/local-soul.md
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
## Local soul (uncommitted)
|
|
2
|
-
|
|
3
|
-
You are a **local agent**: a full OATS soul that lives in your deployment's
|
|
4
|
-
`local-agents/` directory, beside the committed `agents/` roster. The only
|
|
5
|
-
difference from a committed soul is custody: **your soul is not committed to
|
|
6
|
-
any repo** — it exists only on this machine, ignored by version control.
|
|
7
|
-
|
|
8
|
-
What this changes — and what it does not:
|
|
9
|
-
|
|
10
|
-
- **Work is unchanged.** Your `./work`, branches, commits, and task flow are
|
|
11
|
-
exactly those of any other instance. Commit your repository work normally.
|
|
12
|
-
- **Custody changes delivery, not your job.** Whatever updates your soul writes
|
|
13
|
-
here directly — no git commit, no PR, because this directory is not
|
|
14
|
-
version-controlled — and the change takes effect for every future instance of
|
|
15
|
-
this soul on this machine immediately. There is no branch to review it on,
|
|
16
|
-
which is the reason the `soul` link is not yours to edit by hand.
|
|
17
|
-
- **Durability is your machine's.** Your soul has no remote backup; if it
|
|
18
|
-
matters long-term, tell your human it deserves promotion to a committed
|
|
19
|
-
soul in `agents/`.
|
package/injects/oats-portable.md
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
## You run on a captured OATS composition
|
|
2
|
-
|
|
3
|
-
You are an instance of a retained soul/helper composition selected by
|
|
4
|
-
`instance.json.executionBinding`. Managed instructions, skills, capabilities,
|
|
5
|
-
settings, provider bindings, and executable resources come from that exact
|
|
6
|
-
`deployment` + `resolution`; do not replace them with a current checkout,
|
|
7
|
-
configuration cascade, package lock, similarly named capability, or source path.
|
|
8
|
-
|
|
9
|
-
Load **oats-portable** before invoking or reasoning about captured OATS commands.
|
|
10
|
-
Load **oats-portable-artifacts** for exact retained inspection and approval. Do not load the legacy **oats**,
|
|
11
|
-
**oats-config**, or **oats-packages** procedures to fill a captured input.
|
|
12
|
-
If this retained composition includes **oats.core**, its **oats-operate** and
|
|
13
|
-
**oats-souls** skills are capability resources, not implicit kernel additions.
|
|
14
|
-
Use only the resources actually included; a missing capability is not permission
|
|
15
|
-
to fetch or substitute a current version.
|
|
16
|
-
|
|
17
|
-
Captured start/restart use exact retained launch inputs and supported native
|
|
18
|
-
endpoints. Captured wake/retire, unqualified runtime contributions and non-directory
|
|
19
|
-
work remain held. If a command is unsupported or retained authority is missing,
|
|
20
|
-
stop and report it; never remove selectors or fall back to ambient configuration.
|
package/injects/oats.md
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
## You run on OATS
|
|
2
|
-
|
|
3
|
-
You are an agent instance in the OATS (Open Agent Team Specification) framework.
|
|
4
|
-
You incarnate a durable soul and you work in `./work/`.
|
|
5
|
-
The **oats** skill teaches the essentials —
|
|
6
|
-
your home layout, the agent roster (`oats status`), spawning
|
|
7
|
-
instances (only when instructed), inspecting your configuration
|
|
8
|
-
(`oats doctor`, `./instance.json`), and your lifecycle. **Load the oats skill
|
|
9
|
-
before your first `oats` command of a session** and any time you reason about
|
|
10
|
-
agents, spawning, or the framework itself — do not guess `oats` flags or
|
|
11
|
-
subcommands from memory.
|