@awebai/oats 0.22.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/LICENSE +21 -0
- package/README.md +380 -0
- package/bin/oats.mjs +3294 -0
- package/capabilities/oats-authoring/oats.json +12 -0
- package/capabilities/oats-aweb/bin/oats-aweb.mjs +297 -0
- package/capabilities/oats-aweb/injects/aweb.md +55 -0
- package/capabilities/oats-aweb/oats.json +47 -0
- package/capabilities/oats-aweb/package.json +20 -0
- package/capabilities/oats-jira/bin/oats-jira.mjs +40 -0
- package/capabilities/oats-jira/injects/jira.md +10 -0
- package/capabilities/oats-jira/oats.json +22 -0
- package/capabilities/oats-jira/package.json +25 -0
- package/capabilities/oats-jira/skills/jira-tasks/SKILL.md +176 -0
- package/capabilities/oats-linear/README.md +234 -0
- package/capabilities/oats-linear/bin/oats-linear-hook.mjs +32 -0
- package/capabilities/oats-linear/bin/oats-linear.mjs +344 -0
- package/capabilities/oats-linear/injects/linear.md +8 -0
- package/capabilities/oats-linear/oats.json +24 -0
- package/capabilities/oats-linear/package.json +29 -0
- package/capabilities/oats-linear/skills/linear-tasks/SKILL.md +217 -0
- package/capabilities/oats-linear/test/oats-linear.test.mjs +168 -0
- package/capabilities/oats-okf/agents/memory-harvest.md +25 -0
- package/capabilities/oats-okf/bin/oats-okf.mjs +283 -0
- package/capabilities/oats-okf/injects/okf.md +62 -0
- package/capabilities/oats-okf/oats.json +20 -0
- package/capabilities/oats-okf/package.json +22 -0
- package/capabilities/oats-okf/skills/memory-harvest/SKILL.md +100 -0
- package/capabilities/oats-okf/skills/okf/SKILL.md +107 -0
- package/capabilities/oats-okf/skills/okf/scripts/okf-validate.mjs +123 -0
- package/capabilities/oats-review/agents/reviewer/AGENTS.md +53 -0
- package/capabilities/oats-review/agents/reviewer/soul.yaml +6 -0
- package/capabilities/oats-review/injects/review.md +68 -0
- package/capabilities/oats-review/oats.json +10 -0
- package/capabilities/oats-review/skills/code-review/SKILL.md +44 -0
- package/capabilities/oats-review/skills/security-review/SKILL.md +59 -0
- package/docs/capabilities.md +505 -0
- package/docs/capability-manifest.schema.json +223 -0
- package/docs/configuration.md +482 -0
- package/docs/conventions.md +73 -0
- package/docs/design/desktop-ux-plan.md +362 -0
- package/docs/design/package-engine-contract.md +813 -0
- package/docs/design/package-runtime-api.md +414 -0
- package/docs/desktop-cli-api.md +89 -0
- package/docs/desktop-succession.md +51 -0
- package/docs/desktop.md +187 -0
- package/docs/implementation.md +282 -0
- package/docs/integrations.md +123 -0
- package/docs/knowledge-theory.md +97 -0
- package/docs/knowledge.md +139 -0
- package/docs/layers.md +110 -0
- package/docs/migration-from-oas.md +122 -0
- package/docs/oats-config.schema.json +140 -0
- package/docs/oats-lock.schema.json +175 -0
- package/docs/oats-package.schema.json +129 -0
- package/docs/packages.md +442 -0
- package/docs/release-lane.md +132 -0
- package/docs/release-notes/v0.18.2.md +79 -0
- package/docs/release-notes/v0.18.3.md +63 -0
- package/docs/release-notes/v0.18.4.md +65 -0
- package/docs/release-notes/v0.18.5.md +66 -0
- package/docs/release-notes/v0.18.6.md +87 -0
- package/docs/release-notes/v0.19.0.md +186 -0
- package/docs/release-notes/v0.19.1.md +24 -0
- package/docs/release-notes/v0.19.2.md +32 -0
- package/docs/release-notes/v0.19.3.md +16 -0
- package/docs/release-notes/v0.19.4.md +12 -0
- package/docs/release-notes/v0.20.0.md +89 -0
- package/docs/release-notes/v0.22.0.md +180 -0
- package/docs/souls-and-instances.md +344 -0
- package/injects/framework-workspace.md +7 -0
- package/injects/instance-boundary.md +43 -0
- package/injects/local-soul.md +19 -0
- package/injects/oats.md +11 -0
- package/injects/work-attached.md +16 -0
- package/injects/work-checkout.md +12 -0
- package/injects/work-workspace.md +22 -0
- package/injects/work-worktree.md +13 -0
- package/lib/core.mjs +6792 -0
- package/lib/packages.mjs +1375 -0
- package/lib/tmux-config.mjs +35 -0
- package/package-catalog.json +44 -0
- package/package.json +55 -0
- package/packages/record/README.md +151 -0
- package/packages/record/bin/capture.mjs +256 -0
- package/packages/record/bin/recall.mjs +102 -0
- package/packages/record/bin/setup.mjs +281 -0
- package/packages/record/bin/turn-record.mjs +47 -0
- package/packages/record/docs/turn-record-sot.md +350 -0
- package/packages/record/lib/canonical.mjs +151 -0
- package/packages/record/lib/capture-aw.mjs +179 -0
- package/packages/record/lib/capture-cc.mjs +322 -0
- package/packages/record/lib/formats.mjs +296 -0
- package/packages/record/lib/ignore.mjs +155 -0
- package/packages/record/lib/index-db.mjs +524 -0
- package/packages/record/lib/project-aweb.mjs +251 -0
- package/packages/record/lib/segments.mjs +186 -0
- package/packages/record/lib/store.mjs +447 -0
- package/packages/record/lib/tags.mjs +114 -0
- package/packages/record/package.json +45 -0
- package/packages/record/test/vectors/README.md +34 -0
- package/packages/record/test/vectors/aweb-projection-v1.json +231 -0
- package/packages/record/test/vectors/journal-merge-v1.json +261 -0
- package/packages/record/test/vectors/turn-id-v1.json +152 -0
- package/packages/record/test/vectors/validate.mjs +391 -0
- package/skills/integration-authoring/SKILL.md +76 -0
- package/skills/oats/SKILL.md +151 -0
- package/skills/oats-config/SKILL.md +162 -0
- package/skills/oats-getting-started/SKILL.md +159 -0
- package/skills/oats-packages/SKILL.md +180 -0
- package/skills/oats-support/SKILL.md +79 -0
- package/skills/skill-craft/SKILL.md +109 -0
- package/skills/soul-craft/SKILL.md +109 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
OATS configuration lives in `oats-config.yaml` at a laptop, workspace, or
|
|
4
|
+
repository root. It owns deployment policy: agent-type declarations, the three
|
|
5
|
+
fundamental layer slots, additive capability activations, settings,
|
|
6
|
+
exclusions, instruction overrides, and work modes.
|
|
7
|
+
|
|
8
|
+
The CLI is the primary config author: `oats init` scaffolds the full shape,
|
|
9
|
+
`oats use` writes capability entries, `oats create --type` sets a soul's type.
|
|
10
|
+
Hand-editing is valid but never required. Packages never declare their
|
|
11
|
+
targets. See the machine-readable
|
|
12
|
+
[`oats-config.schema.json`](oats-config.schema.json) alongside the examples
|
|
13
|
+
below.
|
|
14
|
+
|
|
15
|
+
## Scopes
|
|
16
|
+
|
|
17
|
+
Resolution walks from the soul's repository upward:
|
|
18
|
+
|
|
19
|
+
1. repository;
|
|
20
|
+
2. containing workspace(s); and
|
|
21
|
+
3. laptop/home.
|
|
22
|
+
|
|
23
|
+
A `global` binding applies to all souls governed by the level that declares
|
|
24
|
+
it. It does not escape that scope. This lets a laptop set defaults, a workspace
|
|
25
|
+
add shared team capabilities, and one repository make a narrower choice.
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
~/oats-config.yaml
|
|
29
|
+
~/workspace/oats-config.yaml
|
|
30
|
+
~/workspace/service/oats-config.yaml
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Use `oats doctor <context> --soul <name>` to inspect the result.
|
|
34
|
+
|
|
35
|
+
## Schema
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
name: example-service
|
|
39
|
+
|
|
40
|
+
# ── Team — the deployment boundary. The closest scope declaring team: wins;
|
|
41
|
+
# every repo under it resolves the same team (identity, discovery, messaging).
|
|
42
|
+
team:
|
|
43
|
+
name: example-engineering
|
|
44
|
+
# id: example-engineering:example.com # explicit provider team id (e.g. aweb <name>:<namespace>)
|
|
45
|
+
|
|
46
|
+
# ── Agent types (families) ── declared here by name; each soul opts in via
|
|
47
|
+
# `type: <name>` in its soul.yaml. Capability entries can target them.
|
|
48
|
+
agent-types:
|
|
49
|
+
developers:
|
|
50
|
+
description: Agents that build and maintain the service
|
|
51
|
+
reviewers:
|
|
52
|
+
description: Agents that review changes
|
|
53
|
+
|
|
54
|
+
capabilities:
|
|
55
|
+
# Fundamental layers — exclusive slots; a capability entry or an explicit none.
|
|
56
|
+
layers:
|
|
57
|
+
knowledge:
|
|
58
|
+
capability: oats.okf
|
|
59
|
+
from: installed
|
|
60
|
+
settings:
|
|
61
|
+
harvest-model: github-copilot/gpt-5.5
|
|
62
|
+
# injection-override: .agents/injections/capabilities/oats.okf.md
|
|
63
|
+
messaging: none
|
|
64
|
+
tasks:
|
|
65
|
+
capability: oats.linear
|
|
66
|
+
from: installed
|
|
67
|
+
agent-types:
|
|
68
|
+
developers:
|
|
69
|
+
enabled: true
|
|
70
|
+
settings: {team: ENG}
|
|
71
|
+
# injection-override: .agents/injections/capabilities/oats.linear.md
|
|
72
|
+
|
|
73
|
+
# Additive capabilities — non-exclusive; target global, agent-types, or souls.
|
|
74
|
+
additive:
|
|
75
|
+
example.review:
|
|
76
|
+
from: installed
|
|
77
|
+
agent-types:
|
|
78
|
+
developers:
|
|
79
|
+
enabled: true
|
|
80
|
+
settings:
|
|
81
|
+
depth: normal
|
|
82
|
+
souls:
|
|
83
|
+
security-reviewer:
|
|
84
|
+
enabled: true
|
|
85
|
+
settings:
|
|
86
|
+
depth: exhaustive
|
|
87
|
+
# injection-override: .agents/injections/capabilities/example.review.md
|
|
88
|
+
|
|
89
|
+
skill-overrides:
|
|
90
|
+
review: example.review
|
|
91
|
+
|
|
92
|
+
# ── Work modes — optional per-mode env bootstrap (briefings are packaged, not overridable).
|
|
93
|
+
work-modes:
|
|
94
|
+
worktree:
|
|
95
|
+
# Runs inside each NEW worktree right after `git worktree add` — env setup
|
|
96
|
+
# scripts (installs, .env copying, direnv/mise). Relative to this config's dir.
|
|
97
|
+
setup: scripts/setup-worktree.sh
|
|
98
|
+
|
|
99
|
+
# ── OATS defaults — the framework's baseline instruction block.
|
|
100
|
+
oats:
|
|
101
|
+
# injection-override: .agents/injections/oats-defaults/oats.md
|
|
102
|
+
|
|
103
|
+
# Extra unconditional instruction blocks for every instance at this scope.
|
|
104
|
+
agents-md-injection:
|
|
105
|
+
repository: injects/repository.md
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `team`
|
|
109
|
+
|
|
110
|
+
`team:` declares the deployment boundary — typically at the workspace scope.
|
|
111
|
+
The closest scope declaring it wins, so every repo under `~/lfx` resolves the
|
|
112
|
+
same team. `name:` is required; `id:` optionally pins the provider team id
|
|
113
|
+
(for aweb, the canonical `<name>:<namespace>` form). Three things hang off
|
|
114
|
+
it:
|
|
115
|
+
|
|
116
|
+
- **Identity**: instances record their team in `instance.json` and their
|
|
117
|
+
TASK.md briefing; hooks receive `OATS_TEAM_NAME`/`OATS_TEAM_ID`/`OATS_TEAM_SCOPE`.
|
|
118
|
+
- **Discovery**: `oats status --team` lists agents across every `agents/`
|
|
119
|
+
root in the team scope (the scope's own plus each member repo's), so an
|
|
120
|
+
agent in one repo can see teammates defined at the workspace level or in
|
|
121
|
+
sibling repos. There is no explicit member list — every repo under the
|
|
122
|
+
team scope is a member by construction.
|
|
123
|
+
- **Cross-repo spawn/retire**: `oats spawn <soul>` and `oats retire <instance>`
|
|
124
|
+
resolve across the team scope's repos when the name isn't found locally
|
|
125
|
+
(unique match wins; ambiguity errors with guidance to pass `--dir`). The
|
|
126
|
+
instance homes with the soul's own repo, works in that repo, and resolves
|
|
127
|
+
that repo's config chain — spawning from elsewhere changes nothing about
|
|
128
|
+
the instance itself.
|
|
129
|
+
- **Messaging**: the aweb integration joins spawned instances into the
|
|
130
|
+
resolved team (id wins over name; a bare name is resolved against the aweb
|
|
131
|
+
root's memberships), with the instance name as the discoverable alias.
|
|
132
|
+
Because every instance joins with its own name, the aweb team roster is
|
|
133
|
+
also the **cross-machine directory**: `oats aweb roster` lists team members
|
|
134
|
+
wherever they run, complementing the local `oats status --team`.
|
|
135
|
+
|
|
136
|
+
### `agent-types`
|
|
137
|
+
|
|
138
|
+
Agent types are agent families. Config declares type names (optionally with a
|
|
139
|
+
description); membership is **not** listed in config — each soul opts in with
|
|
140
|
+
an optional single `type: <name>` in its `soul.yaml` (`oats create --type <t>`
|
|
141
|
+
sets it; `oats type add <name>` declares it in config). A type is identity: what kind of agent a soul is travels with the
|
|
142
|
+
soul, while config decides what each type gets. Tags, dynamic selectors, and
|
|
143
|
+
instance names are not supported.
|
|
144
|
+
|
|
145
|
+
### `capabilities.layers`
|
|
146
|
+
|
|
147
|
+
The three fundamental layers — `knowledge`, `messaging`, `tasks` — are
|
|
148
|
+
exclusive slots with an explicit home. Each slot holds either a capability
|
|
149
|
+
entry (`capability: <id>` plus optional `from`, targets, `settings`,
|
|
150
|
+
`injection-override`) or the explicit string `none`, which suppresses an integration
|
|
151
|
+
inherited from an outer scope. A slot absent from a config inherits from
|
|
152
|
+
outer scopes; `oats init` writes all three so the resolution is visible.
|
|
153
|
+
|
|
154
|
+
The entry's capability must declare the same layer in its manifest; a
|
|
155
|
+
mismatch is an error, as is a layer-declaring capability placed under
|
|
156
|
+
`additive`. A layer entry with no explicit targets is globally enabled at
|
|
157
|
+
that scope.
|
|
158
|
+
|
|
159
|
+
### `capabilities.additive`
|
|
160
|
+
|
|
161
|
+
Additive capabilities are non-exclusive packages keyed by capability ID. A
|
|
162
|
+
declaration without `global`, `agent-types`, or `souls` is acquired but
|
|
163
|
+
inactive. A target value can be `true`, `false`, or an object containing
|
|
164
|
+
`enabled` and `settings`.
|
|
165
|
+
|
|
166
|
+
For a soul, matching global, agent-type, and soul bindings compose. Setting
|
|
167
|
+
precedence is:
|
|
168
|
+
|
|
169
|
+
1. soul;
|
|
170
|
+
2. matching agent-type;
|
|
171
|
+
3. global;
|
|
172
|
+
4. at equal target specificity, closer config scope.
|
|
173
|
+
|
|
174
|
+
Conflicting values at equal specificity and the same scope are errors. OATS
|
|
175
|
+
never uses YAML order as an implicit winner. `enabled: false` uses the same
|
|
176
|
+
precedence, allowing global enable → type exclusion → soul re-enable.
|
|
177
|
+
|
|
178
|
+
### `from` (provenance)
|
|
179
|
+
|
|
180
|
+
`from:` documents where the artifact must come from, and resolution enforces
|
|
181
|
+
it: `installed` (acquired into `.agents/capabilities/installed/`,
|
|
182
|
+
lock-governed — from the official marketplace by id, a git URL, or a local
|
|
183
|
+
path), `owned` (authored at this scope under `.agents/capabilities/owned/`),
|
|
184
|
+
or `path:<dir>` (development declaration pointing at a manifest directory).
|
|
185
|
+
A mismatch between `from:` and the discovered artifact origin is an error.
|
|
186
|
+
`from: bundled` was removed. Official capabilities are acquired like any other
|
|
187
|
+
package, and acquisition never grants executable trust — approve executable
|
|
188
|
+
surfaces explicitly with `oats trust <capability>`.
|
|
189
|
+
|
|
190
|
+
### `injection-override`
|
|
191
|
+
|
|
192
|
+
Every injectable item — each capability entry, each work mode, and the `oats:`
|
|
193
|
+
kernel block — accepts an `injection-override:` key: a config-relative path replaces
|
|
194
|
+
the packaged instruction file, `none` suppresses it, and `default` restores
|
|
195
|
+
it. The closest scope declaring the key wins. Scaffolded configs carry these
|
|
196
|
+
as commented-out lines pointing at the conventional locations:
|
|
197
|
+
|
|
198
|
+
```text
|
|
199
|
+
.agents/injections/capabilities/<capability-id>.md
|
|
200
|
+
.agents/injections/oats-defaults/oats.md
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The clean path is `oats inject eject <capability|oats>`: it copies
|
|
204
|
+
the packaged default to the conventional path and sets the key — the ejected
|
|
205
|
+
file then deliberately stops tracking package updates. Overrides are not
|
|
206
|
+
allowed on `from: owned`/`path:` entries: the scope owns the package source,
|
|
207
|
+
so its `injects/` file is edited directly.
|
|
208
|
+
|
|
209
|
+
### `skill-overrides`
|
|
210
|
+
|
|
211
|
+
Spawn fails when two sources contribute the same skill directory name. An
|
|
212
|
+
explicit override maps that name to the winning source (`soul`, `kernel`, a
|
|
213
|
+
capability ID, or a config source shown by doctor). Overrides are deliberate;
|
|
214
|
+
OATS never keeps whichever filesystem entry happened to be discovered first.
|
|
215
|
+
|
|
216
|
+
### Instruction sources
|
|
217
|
+
|
|
218
|
+
`agents-md-injection` adds unconditional config-owned instruction files (it
|
|
219
|
+
adds content; it does not override packaged defaults — that is `injection-override:`).
|
|
220
|
+
Capability packages can ship an `inject`; work modes have their own source.
|
|
221
|
+
|
|
222
|
+
OATS reads the canonical soul `AGENTS.md`, composes selected blocks in a new
|
|
223
|
+
instance file, and records every source. It never reconciles deployment
|
|
224
|
+
instructions into the committed soul; spawn and doctor are the composition
|
|
225
|
+
boundaries.
|
|
226
|
+
|
|
227
|
+
### Work modes
|
|
228
|
+
|
|
229
|
+
Work modes remain soul/instance topology, not capability packages:
|
|
230
|
+
|
|
231
|
+
- `worktree`: dedicated branch/worktree;
|
|
232
|
+
- `checkout`: shared current checkout;
|
|
233
|
+
- `attached`: another instance's work tree;
|
|
234
|
+
- `workspace`: the whole team scope — cross-repo coordinators that read all
|
|
235
|
+
member repos but never edit them (their soul's knowledge updates arrive as
|
|
236
|
+
PRs to the soul's home repo).
|
|
237
|
+
|
|
238
|
+
Work-mode briefings are packaged with the kernel and are not overridable;
|
|
239
|
+
the only work-mode configuration is `setup:` — an env-bootstrap command that
|
|
240
|
+
runs inside each fresh worktree after creation (a lot of teams prefer a
|
|
241
|
+
script that sets up the environment: installs, .env copying, direnv/mise).
|
|
242
|
+
Its failure warns without hiding the instance.
|
|
243
|
+
|
|
244
|
+
## Acquisition and lockfile
|
|
245
|
+
|
|
246
|
+
External acquisition writes `oats-lock.json` beside the declaring config in
|
|
247
|
+
`lockfileVersion: 2`. It records two levels — a `packages` map (source, exact
|
|
248
|
+
commit, selected path, payload integrity, dependencies) and a `capabilities`
|
|
249
|
+
map (each materialized capability's version, provider package, path, artifact
|
|
250
|
+
integrity, and executable trust):
|
|
251
|
+
|
|
252
|
+
```json
|
|
253
|
+
{
|
|
254
|
+
"lockfileVersion": 2,
|
|
255
|
+
"packages": {
|
|
256
|
+
"example.engineering": {
|
|
257
|
+
"source": "git:https://example.invalid/engineering.git@v1.4.2",
|
|
258
|
+
"version": "1.4.2",
|
|
259
|
+
"commit": "0123456789abcdef0123456789abcdef01234567",
|
|
260
|
+
"path": "oats-package",
|
|
261
|
+
"integrity": "sha256-…",
|
|
262
|
+
"dependencies": []
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"capabilities": {
|
|
266
|
+
"example.review": {
|
|
267
|
+
"version": "1.4.2",
|
|
268
|
+
"package": "example.engineering",
|
|
269
|
+
"path": "capabilities/example-review",
|
|
270
|
+
"integrity": "sha256-…",
|
|
271
|
+
"trusted": false
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
No command silently updates this record. Changed capability integrity blocks the
|
|
278
|
+
artifact and resets its trust. `oats trust <id>` approves commands, hooks, and
|
|
279
|
+
launch-environment authority only for the exact locked artifact integrity, and
|
|
280
|
+
official identity never grants it.
|
|
281
|
+
Declarative skill/instruction capabilities need a valid lock but no executable
|
|
282
|
+
approval. Capabilities authored under a scope's `.agents/capabilities/owned/`
|
|
283
|
+
follow their reviewed source provenance. Materialized artifacts live in
|
|
284
|
+
`.agents/capabilities/installed/<id>/` beside their lock, stay gitignored, and
|
|
285
|
+
are re-materialized by bare `oats install` with integrity verification.
|
|
286
|
+
|
|
287
|
+
Legacy `lockfileVersion: 1` locks (per-capability marketplace installs) remain
|
|
288
|
+
readable and usable. `oats migrate` converts a scope to the revised v2 lock
|
|
289
|
+
**all-or-nothing**: if any entry cannot map to a package yet, the whole scope
|
|
290
|
+
stays byte-identical v1 and keeps working, and a successful run converts the
|
|
291
|
+
entire scope at once. There is no residue container — a converted lock never
|
|
292
|
+
carries leftover v1 entries. The earlier transitional v2 shape — capability
|
|
293
|
+
lists on package rows, a persistent `.agents/packages/installed/` store — is
|
|
294
|
+
rejected as an invalid lock and recreated by a fresh acquisition, never
|
|
295
|
+
migrated. See `docs/capabilities.md` (“Distribution packages”), the schemas
|
|
296
|
+
`docs/oats-package.schema.json` / `docs/oats-lock.schema.json`, and
|
|
297
|
+
`docs/design/package-engine-contract.md`.
|
|
298
|
+
|
|
299
|
+
## CLI
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
oats init [--raw] [--template <name|path|git-url>] [--knowledge <id|none>] [--messaging <id|none>] [--tasks <id|none>]
|
|
303
|
+
oats install [<id|git-url|path>] [--dir <dir>] # acquire; bare form restores; inactive by default
|
|
304
|
+
oats trust <capability> [--dir <dir>]
|
|
305
|
+
oats use <capability> [--global|--type <t>|--soul <s>] [--disable] [--settings k=v [k2=v2 ...]]
|
|
306
|
+
oats use none --layer <layer>
|
|
307
|
+
oats type add <name> [--description <d>] # declare an agent type
|
|
308
|
+
oats type list
|
|
309
|
+
oats inject eject <capability|oats> # materialize an injection override
|
|
310
|
+
oats create <name> --type <agent-type> ...
|
|
311
|
+
oats doctor [context] --soul <name> [--json]
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
`oats init` writes only explicitly selected defaults, acquiring marketplace
|
|
315
|
+
layer capabilities into this scope's installed/ store as needed; it does not
|
|
316
|
+
activate every acquired package. `oats use`
|
|
317
|
+
places a layer-declaring capability under `capabilities.layers.<layer>` and
|
|
318
|
+
everything else under `capabilities.additive`, regenerating the conventional
|
|
319
|
+
injection comments; custom comments inside the `capabilities:` block are not
|
|
320
|
+
preserved.
|
|
321
|
+
|
|
322
|
+
`oats use` activates **into a config file**, so it needs one at this scope or an
|
|
323
|
+
outer one. In a scope with no `oats-config.yaml` anywhere in its chain, a
|
|
324
|
+
capability already present in that scope's own `installed/` or `owned/` store
|
|
325
|
+
fails with `E_NO_CONFIG` naming the initialization to run first — exactly
|
|
326
|
+
`oats init --raw --dir <scope>`, which is offline, deterministic and writes only
|
|
327
|
+
the minimal config — and then the same `oats use` command again. It never
|
|
328
|
+
reports the capability as unacquired, and it writes nothing: authoring a
|
|
329
|
+
scope's first config is `oats init`'s job.
|
|
330
|
+
|
|
331
|
+
### Templates
|
|
332
|
+
|
|
333
|
+
`oats init --template <name|path|git-url>` seeds the new config from a template
|
|
334
|
+
config file: a local path, a git URL whose default branch carries an
|
|
335
|
+
`oats-config.yaml`, or a name resolved through a `templates:` map declared in an
|
|
336
|
+
outer scope (typically the laptop config):
|
|
337
|
+
|
|
338
|
+
```yaml
|
|
339
|
+
# ~/oats-config.yaml
|
|
340
|
+
templates:
|
|
341
|
+
personal: ~/templates/personal-oats-config.yaml
|
|
342
|
+
team: https://example.invalid/oats-templates.git
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
A template seed is copied once. `init` copies the content, records provenance in
|
|
346
|
+
a leading `# template:` comment, rewrites `name:`, strips the `templates:` map,
|
|
347
|
+
and runs a restore so declared external capabilities are present. Later template
|
|
348
|
+
edits never propagate silently.
|
|
349
|
+
|
|
350
|
+
### Package config templates
|
|
351
|
+
|
|
352
|
+
When the config and its capability providers travel together, prefer
|
|
353
|
+
`oats init --package <source> [--config <name>]`. It validates a reference config
|
|
354
|
+
template shipped by a distribution package and writes it as your local
|
|
355
|
+
`oats-config.yaml`, recording the exact template as a commit-safe adopted base
|
|
356
|
+
with package, template, and commit provenance. `oats config diff` and
|
|
357
|
+
`oats config sync` compare against that base later. Installing the package alone
|
|
358
|
+
adopts no template. See [Distribution packages](packages.md).
|
|
359
|
+
|
|
360
|
+
## Fundamental-layer disable
|
|
361
|
+
|
|
362
|
+
An inner scope can suppress an inherited integration without selecting a
|
|
363
|
+
replacement:
|
|
364
|
+
|
|
365
|
+
```yaml
|
|
366
|
+
capabilities:
|
|
367
|
+
layers:
|
|
368
|
+
tasks: none
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
`oats use none --layer tasks` writes this. Pre-v0.9 spellings (`groups:`,
|
|
372
|
+
top-level `layers:`, flat `capabilities.<id>` maps, `source:`,
|
|
373
|
+
`agents-md-injection` on capability entries) are rejected with pointed
|
|
374
|
+
migration errors. Key names are matched as own properties only, so a key
|
|
375
|
+
spelled `constructor` or `toString` is reported as an unsupported key, never as
|
|
376
|
+
a renamed one. `__proto__` is refused outright by every YAML reader — the
|
|
377
|
+
kernel's and the desktop app's own read-only reader — and by the commands that
|
|
378
|
+
WRITE config keys (`oats use --settings`, `--soul`, `--type`), all with
|
|
379
|
+
`unsafe-config-key`: assigning it rewrites the parsed mapping's prototype
|
|
380
|
+
instead of becoming data, which would hide the entry from every key validator.
|
|
381
|
+
The kernel fails closed and reports the offending file; the desktop reader
|
|
382
|
+
degrades that document to "not visible", per its read-only contract.
|
|
383
|
+
|
|
384
|
+
Text that cannot be written as ONE YAML scalar on one line is refused. The
|
|
385
|
+
policed inputs are exactly: `oats use --settings` keys and values, `oats use
|
|
386
|
+
--soul` and `--type` names, `oats type add --description`, and the scaffolded
|
|
387
|
+
`name:` value that `oats init` (in every form) and the first `oats use` / `oats
|
|
388
|
+
type add` at a fresh scope take from the target directory's basename — a
|
|
389
|
+
basename is filesystem input, so one carrying a newline would otherwise write
|
|
390
|
+
arbitrary top-level blocks into the config.
|
|
391
|
+
|
|
392
|
+
Refused: a control character (a newline in a `--settings` value used to inject
|
|
393
|
+
whole extra capability entries into the file) or one of the three line breaks
|
|
394
|
+
outside that range (U+0085, U+2028, U+2029 — U+2028/U+2029 made the reader drop
|
|
395
|
+
the written line entirely, so the command reported success for a setting that
|
|
396
|
+
was not there afterwards); leading or trailing whitespace a read would strip; a
|
|
397
|
+
leading YAML structure indicator (`#`, `|`, `>`, `&`, `*`, `!`, `%`, `@`,
|
|
398
|
+
`` ` ``, `,`, a quote, a flow bracket, or `- `/`? `/`: `); for a VALUE, an
|
|
399
|
+
embedded `" #"` (which opens a trailing comment, so the rest would be dropped
|
|
400
|
+
on read) and an empty value (`key:` with nothing after it reads back as an
|
|
401
|
+
empty map, not an empty string); and — for keys and `--soul`/`--type` names —
|
|
402
|
+
the `:` and `#` that end a key token. Those fail with `unsafe-config-value`
|
|
403
|
+
(values, the scaffolded name included) or `unsafe-config-key` (keys and names),
|
|
404
|
+
and nothing is written.
|
|
405
|
+
|
|
406
|
+
The guarantee is a round trip through the OATS reader, not conformance to an
|
|
407
|
+
external YAML parser: ordinary values are untouched because those characters
|
|
408
|
+
are structural only in first position, so `expr=2 > 1`, `tag=v1.0#build`,
|
|
409
|
+
`list=a,b` and even `mode=a: b` come back exactly as they were written.
|
|
410
|
+
|
|
411
|
+
## Worked examples
|
|
412
|
+
|
|
413
|
+
### All souls use OKF; only developers use Linear
|
|
414
|
+
|
|
415
|
+
```yaml
|
|
416
|
+
agent-types:
|
|
417
|
+
developers:
|
|
418
|
+
description: Souls with type: developers in their soul.yaml
|
|
419
|
+
capabilities:
|
|
420
|
+
layers:
|
|
421
|
+
knowledge:
|
|
422
|
+
capability: oats.okf
|
|
423
|
+
from: installed
|
|
424
|
+
tasks:
|
|
425
|
+
capability: oats.linear
|
|
426
|
+
from: installed
|
|
427
|
+
agent-types:
|
|
428
|
+
developers:
|
|
429
|
+
enabled: true
|
|
430
|
+
settings: {team: ENG, project: Product}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Laptop default with repository exclusion
|
|
434
|
+
|
|
435
|
+
Laptop:
|
|
436
|
+
|
|
437
|
+
```yaml
|
|
438
|
+
capabilities:
|
|
439
|
+
layers:
|
|
440
|
+
messaging:
|
|
441
|
+
capability: oats.aweb
|
|
442
|
+
from: installed
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
Solo repository:
|
|
446
|
+
|
|
447
|
+
```yaml
|
|
448
|
+
capabilities:
|
|
449
|
+
layers:
|
|
450
|
+
messaging: none
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### One marketplace capability for one soul
|
|
454
|
+
|
|
455
|
+
```yaml
|
|
456
|
+
capabilities:
|
|
457
|
+
additive:
|
|
458
|
+
vendor.security-review:
|
|
459
|
+
from: installed
|
|
460
|
+
souls:
|
|
461
|
+
security-reviewer: true
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
Acquire and trust executable surfaces before spawn; target activation alone
|
|
465
|
+
does not download, update, or approve code.
|
|
466
|
+
|
|
467
|
+
## Tmux scrolling during init
|
|
468
|
+
|
|
469
|
+
Interactive `oats init` offers to add `set -g mouse on` to the existing
|
|
470
|
+
`~/.tmux.conf` or XDG tmux config so agent windows scroll normally with a mouse
|
|
471
|
+
or trackpad. It never changes terminal keyboard mappings. Agent-led and
|
|
472
|
+
scripted setup should pass the user's answer explicitly:
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
oats init --tmux-mouse
|
|
476
|
+
oats init --no-tmux-mouse
|
|
477
|
+
oats init --raw --tmux-mouse
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
An accepted change is idempotent and reloads a running tmux server when
|
|
481
|
+
possible. This machine preference is separate from capability acquisition and
|
|
482
|
+
activation.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Conventions — canonical files and generated views
|
|
2
|
+
|
|
3
|
+
OATS uses one canonical source for durable soul content and generated,
|
|
4
|
+
instance-local views for deployment composition.
|
|
5
|
+
|
|
6
|
+
## Operating documents
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
soul/AGENTS.md # canonical role instructions
|
|
10
|
+
soul/CLAUDE.md -> AGENTS.md
|
|
11
|
+
instance/AGENTS.md # generated regular file
|
|
12
|
+
instance/CLAUDE.md -> AGENTS.md
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Never maintain an independent soul `CLAUDE.md`. Config-dependent capability,
|
|
16
|
+
work-mode, and workspace instructions belong only in generated instance
|
|
17
|
+
`AGENTS.md`; they must not be reconciled into the committed soul.
|
|
18
|
+
|
|
19
|
+
Generated blocks use `<!-- oats:<source> src=<file> -->` markers for
|
|
20
|
+
provenance. Edit the canonical soul, source file, or target binding, then spawn
|
|
21
|
+
a new instance. `oats doctor --soul <name>` previews the same final composition.
|
|
22
|
+
|
|
23
|
+
## Skills
|
|
24
|
+
|
|
25
|
+
The only OATS-managed runtime skill root is the instance:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
instance/.agents/skills/ # canonical exact set
|
|
29
|
+
instance/.claude/skills -> ../.agents/skills
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Spawn copies kernel + soul-private + active capability skills into real
|
|
33
|
+
instance-local directories there. Directory symlinks are not used because
|
|
34
|
+
harness recursive discovery may not descend through them. Packages retain
|
|
35
|
+
skills in their own artifact; activation selects them for materialization. Config-level `.agents/skills` is not an OATS capability source
|
|
36
|
+
or an ambient runtime discovery root.
|
|
37
|
+
|
|
38
|
+
Pi starts spawned sessions with ambient skill and context discovery disabled
|
|
39
|
+
and the one instance path explicit; its globally configured extensions remain
|
|
40
|
+
enabled. Claude runs provider-native: it reads the instance's `.claude/skills`
|
|
41
|
+
and `CLAUDE.md` symlinks, and the operator's own user and project
|
|
42
|
+
configuration — skills, plugins, settings — stays in effect. Neither runtime
|
|
43
|
+
gets a redirected config home. `composition.materialized.runtimePosture` in
|
|
44
|
+
`instance.json` records what each instance actually exposes.
|
|
45
|
+
`oats-getting-started` is the sole pre-workspace ambient bootstrap.
|
|
46
|
+
|
|
47
|
+
Duplicate skill directory names are errors unless config's `skill-overrides`
|
|
48
|
+
selects a source.
|
|
49
|
+
|
|
50
|
+
## Package locations
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
<package>/capabilities/<name>/oats.json # the official marketplace (install source, not ambient)
|
|
54
|
+
<level>/.agents/capabilities/installed/<name>/oats.json # acquired (gitignored, restorable)
|
|
55
|
+
<level>/.agents/capabilities/owned/<name>/oats.json # authored at this scope (source; committed where the scope is a repo)
|
|
56
|
+
<level>/oats-lock.json # external source/integrity/trust
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Quick map
|
|
60
|
+
|
|
61
|
+
| Thing | Canonical location |
|
|
62
|
+
|---|---|
|
|
63
|
+
| Config | `<level>/oats-config.yaml` |
|
|
64
|
+
| Acquisition lock | `<level>/oats-lock.json` |
|
|
65
|
+
| Soul operating doc | `soul/AGENTS.md` |
|
|
66
|
+
| Soul Claude view | `soul/CLAUDE.md -> AGENTS.md` |
|
|
67
|
+
| Soul-private skills | `soul/skills/` |
|
|
68
|
+
| Instance operating doc | `instance/AGENTS.md` (generated) |
|
|
69
|
+
| Instance skill set | `instance/.agents/skills/` |
|
|
70
|
+
| Instance metadata | `instance/instance.json` |
|
|
71
|
+
|
|
72
|
+
Symlinks prevent compatibility paths from drifting. Generated regular files
|
|
73
|
+
separate canonical portable identity from scope-dependent runtime policy.
|