@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
package/docs/desktop.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# OATS Desktop
|
|
2
|
+
|
|
3
|
+
The OATS Desktop app is the control panel for OATS deployments: the agent
|
|
4
|
+
roster and hierarchy, brain/markdown/task/state views, and real terminal
|
|
5
|
+
attach to running agents' tmux sessions. With a compatible `oats` CLI
|
|
6
|
+
installed it can also spawn agents from the Soul roster.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
Download the installer for your platform from the
|
|
11
|
+
[GitHub Release](https://github.com/awebai/oats/releases) assets:
|
|
12
|
+
|
|
13
|
+
| Platform | Artifacts | Notes |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| macOS arm64 (Apple Silicon) | DMG + ZIP | ad-hoc signed — see below |
|
|
16
|
+
| macOS x64 (Intel) | DMG + ZIP | ad-hoc signed — see below |
|
|
17
|
+
| Linux x64 | AppImage + DEB | requires `tmux` |
|
|
18
|
+
|
|
19
|
+
**Windows and Linux arm64 are not supported in 0.19.x.**
|
|
20
|
+
|
|
21
|
+
Verify downloads against the release's `SHA256SUMS.txt`. GitHub
|
|
22
|
+
build-provenance attestations are published for every asset
|
|
23
|
+
(`gh attestation verify <file> --repo awebai/oats`).
|
|
24
|
+
|
|
25
|
+
### macOS: ad-hoc signed build
|
|
26
|
+
|
|
27
|
+
The macOS installers are **ad-hoc signed — not Developer ID signed and not
|
|
28
|
+
notarized** (no Apple signing credentials exist; nothing about this release
|
|
29
|
+
claims identified-developer trust). The app bundle carries a complete,
|
|
30
|
+
valid ad-hoc signature — every nested helper and framework is signed and
|
|
31
|
+
the bundle passes `codesign --verify --deep --strict` — but ad-hoc
|
|
32
|
+
signatures carry no identity Gatekeeper can trust, so it will still block
|
|
33
|
+
the first launch of a downloaded (quarantined) copy:
|
|
34
|
+
|
|
35
|
+
- Right-click the app → **Open** → **Open** (once; subsequent launches are
|
|
36
|
+
normal), or
|
|
37
|
+
- `xattr -dr com.apple.quarantine "/Applications/OATS Desktop.app"`.
|
|
38
|
+
|
|
39
|
+
### Linux: prerequisites
|
|
40
|
+
|
|
41
|
+
`tmux` is required for the integrated terminal — the app attaches to your
|
|
42
|
+
agents' tmux sessions. Roster, brain, Markdown and CLI features work without
|
|
43
|
+
it, but opening a terminal will fail until tmux is installed. The DEB
|
|
44
|
+
declares the dependency; for the AppImage install it yourself
|
|
45
|
+
(`apt install tmux`, `dnf install tmux`, …) and verify with `tmux -V`.
|
|
46
|
+
|
|
47
|
+
### The `oats` CLI (for Spawn)
|
|
48
|
+
|
|
49
|
+
Reads — roster, hierarchy, brain, files, terminals — work with no CLI at
|
|
50
|
+
all. Spawning agents runs through an installed `oats` CLI with Desktop API
|
|
51
|
+
v1:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install -g @awebai/oats
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Desktop and the CLI publish in lockstep from one tag, so the matching CLI is
|
|
58
|
+
the one with **this Desktop's own version** — the app's degradation card
|
|
59
|
+
shows that exact `npm install -g @awebai/oats@<version>` command, and
|
|
60
|
+
copying it from the card is the reliable route.
|
|
61
|
+
|
|
62
|
+
Each Desktop accepts a band of released CLI versions around its own —
|
|
63
|
+
prereleases are never accepted — and individual features may sit behind a
|
|
64
|
+
higher floor (spawn-time agent relations do; the relation controls fail closed
|
|
65
|
+
naming the version they need). **The app states both**: the degradation card
|
|
66
|
+
shows the accepted range and the exact install command, and the relation note
|
|
67
|
+
names its floor. This guide deliberately does not repeat those numbers — it is
|
|
68
|
+
rolling documentation and would go stale against the app; the versioned
|
|
69
|
+
[release notes](release-notes/) record the band for each release, and
|
|
70
|
+
[docs/desktop-cli-api.md](desktop-cli-api.md) is the contract of record beside
|
|
71
|
+
the code that enforces it. The app discovers the CLI automatically
|
|
72
|
+
(your PATH, the npm global prefix, a login shell) and re-probes on launch,
|
|
73
|
+
app focus, and Retry. Until a compatible CLI is verified, the Soul roster's
|
|
74
|
+
**Spawn** buttons are disabled behind one card showing what was detected,
|
|
75
|
+
what is required, **Choose oats…** (pick the binary yourself — the choice
|
|
76
|
+
persists), **Retry**, a docs link, and the copyable install command. The
|
|
77
|
+
app never installs anything itself. (Memory harvest runs through the same
|
|
78
|
+
CLI boundary in the backend; it has no dedicated button in this release.)
|
|
79
|
+
|
|
80
|
+
The probe/mutation contract is specified in
|
|
81
|
+
[desktop-cli-api.md](desktop-cli-api.md).
|
|
82
|
+
|
|
83
|
+
## Opening a workspace
|
|
84
|
+
|
|
85
|
+
The app starts on the directory it was launched with (its own folder by
|
|
86
|
+
default). To view a deployment, open the workspace switcher in the sidebar
|
|
87
|
+
and choose **Add workspace → Browse**, then point it at an OATS workspace —
|
|
88
|
+
a directory containing `agents/`, or `local-agents/` for machine-local
|
|
89
|
+
souls, or a team scope whose `oats-config.yaml` declares `team:`. Team scopes
|
|
90
|
+
show every member repo's agents under one roster with a workspace switcher.
|
|
91
|
+
Added workspaces are remembered and offered as suggestions next time.
|
|
92
|
+
|
|
93
|
+
Local souls (uncommitted, machine-local agents under `local-agents/`) are
|
|
94
|
+
first-class: they appear in the roster with a `local` chip, their brains
|
|
95
|
+
and knowledge render, and they spawn like any other soul. Launch flags for
|
|
96
|
+
scripted use: `--dir <workspace>` and `OATS_DESKTOP_PORT`.
|
|
97
|
+
|
|
98
|
+
## Migrating from the web panel / TUI pane
|
|
99
|
+
|
|
100
|
+
0.18.2 removes the legacy `oats.web` browser panel, `oats pane`, and the
|
|
101
|
+
`@awebai/oats/control-pane` export. The Desktop app replaces all
|
|
102
|
+
three. Migration:
|
|
103
|
+
|
|
104
|
+
1. Update the CLI everywhere: `npm install -g @awebai/oats`.
|
|
105
|
+
2. Run `oats doctor` at each workspace scope and follow its guidance to
|
|
106
|
+
remove stale `oats.web` config entries, locks, and installed artifacts.
|
|
107
|
+
3. Install the Desktop app (above) and open your workspace.
|
|
108
|
+
|
|
109
|
+
The full breaking-change list is in the
|
|
110
|
+
[v0.18.2 release notes](release-notes/v0.18.2.md).
|
|
111
|
+
|
|
112
|
+
## Security posture
|
|
113
|
+
|
|
114
|
+
- The bundled backend binds **127.0.0.1 only** and guards against DNS
|
|
115
|
+
rebinding (loopback Host on every request, loopback Origin on POSTs).
|
|
116
|
+
Do not expose it: it can type into your agent terminals.
|
|
117
|
+
- The app never imports framework code from a checkout and accepts no
|
|
118
|
+
framework-root environment override; deployments are read with an
|
|
119
|
+
app-owned read-only reader. All lifecycle mutations go through the
|
|
120
|
+
installed CLI via `execFile` with an absolute binary — never a shell.
|
|
121
|
+
- Task text for spawns travels via an owner-only (0600) tempfile, never
|
|
122
|
+
argv. Harvest always runs in the server-verified instance home.
|
|
123
|
+
- Workspace content is treated as untrusted: symlinked directories never
|
|
124
|
+
widen the file API, and capability packages cannot read outside their
|
|
125
|
+
own tree.
|
|
126
|
+
|
|
127
|
+
## Troubleshooting
|
|
128
|
+
|
|
129
|
+
| Symptom | Cause / fix |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| "Compatible oats CLI required" card | No CLI, or a version outside the range the card itself states. Copy the card's install command, or **Choose oats…** to point at the right binary; **Retry** re-probes. Spawn is disabled until a compatible CLI is verified. |
|
|
132
|
+
| Spawn disabled, no card | The probe hasn't settled yet (transient, resolves in ms). If it persists, the backend is unreachable — restart the app. |
|
|
133
|
+
| Terminals fail to open ("could not attach") | tmux missing, or no live session for that instance. Install tmux (`tmux -V`); check `tmux ls`. |
|
|
134
|
+
| Can't select/copy text in a terminal tab | The terminal runs with tmux mouse handling, so a plain drag scrolls/passes through. Hold **Option** (macOS) or **Shift** while dragging to make a local selection, then copy (Cmd+C / right-click → Copy). |
|
|
135
|
+
| macOS "app is damaged / can't be opened" | Ad-hoc-signed (not notarized) build + quarantine. Right-click → Open, or clear the quarantine attribute (above). If it persists, verify the bundle: `codesign --verify --deep --strict --verbose=2 "/Applications/OATS Desktop.app"` — a non-zero exit means a broken artifact, report it. |
|
|
136
|
+
| Roster empty | The opened directory isn't an OATS workspace (needs `agents/` or `local-agents/`, or a team scope). Use the workspace switcher → Add workspace to select the right root. |
|
|
137
|
+
|
|
138
|
+
For bugs, attach the terminal output of the app (`OATS Desktop` prints
|
|
139
|
+
server and CLI-discovery logs to stdout) and your platform/arch.
|
|
140
|
+
|
|
141
|
+
## Release verification ownership
|
|
142
|
+
|
|
143
|
+
Installer CI gates what headless runners can prove reliably for every
|
|
144
|
+
published platform/architecture: electron-builder completes, the expected
|
|
145
|
+
DMG/ZIP/AppImage/DEB artifacts exist, both packaged macOS `.app` bundles
|
|
146
|
+
pass strict deep codesign verification of their complete ad-hoc signatures
|
|
147
|
+
(`codesign --verify --deep --strict`), node-pty's packaged `spawn-helper` is
|
|
148
|
+
executable, and node-pty loads and spawns under the packaged Electron ABI.
|
|
149
|
+
The macOS x64 leg cross-builds on macos-14 and installs Rosetta 2 so that its
|
|
150
|
+
x64 Electron + node-pty ABI probe really executes; a wrong-architecture
|
|
151
|
+
native module fails that leg.
|
|
152
|
+
|
|
153
|
+
CI does **not** gate the packaged GUI launch: ad-hoc-signed, non-notarized
|
|
154
|
+
Electron apps do not
|
|
155
|
+
have a reliable interactive windowserver in headless CI. Post-publish launch
|
|
156
|
+
acceptance is therefore owned by the operator/maintainer, using the actual
|
|
157
|
+
released installers (not a source checkout):
|
|
158
|
+
|
|
159
|
+
1. Verify the asset checksum/attestation, install it outside the source tree,
|
|
160
|
+
and on macOS use right-click → **Open** for the Gatekeeper step (ad-hoc
|
|
161
|
+
signatures carry no identified-developer identity).
|
|
162
|
+
2. Launch OATS Desktop and open a real deployment; verify roster, brain and
|
|
163
|
+
Markdown reads.
|
|
164
|
+
3. Attach an existing tmux terminal, confirm input/output, and close the tab
|
|
165
|
+
(the durable tmux window must survive).
|
|
166
|
+
4. Verify the released global CLI is detected and Spawn is enabled; hide or
|
|
167
|
+
mismatch the CLI and confirm reads/terminal still work while Spawn disables
|
|
168
|
+
with recovery guidance.
|
|
169
|
+
5. Repeat per published architecture where hardware is available. In
|
|
170
|
+
particular, launch-check macOS x64 on an Intel Mac if one is available;
|
|
171
|
+
CI's Rosetta ABI probe is the native-module proof, while this is the actual
|
|
172
|
+
shipped-installer/user-launch proof.
|
|
173
|
+
|
|
174
|
+
Record the installed version, platform/architecture and outcome in the
|
|
175
|
+
release verification notes. This post-publish check is acceptance — it does
|
|
176
|
+
not weaken the pre-publish build/inventory/ABI gates.
|
|
177
|
+
|
|
178
|
+
## Building from source
|
|
179
|
+
|
|
180
|
+
Developer docs live in [`packages/desktop/README.md`](../packages/desktop/README.md)
|
|
181
|
+
(run, architecture, view contract) — packaging is `npm run dist`
|
|
182
|
+
(electron-builder; macOS ad-hoc signed — not Developer ID, not notarized —
|
|
183
|
+
certificate auto-discovery disabled) and
|
|
184
|
+
`npm run dist:smoke` verifies the packed artifact. Build/release CI uses the
|
|
185
|
+
marked build-verify mode (inventory + strict codesign verification +
|
|
186
|
+
node-pty ABI, no GUI launch); a local
|
|
187
|
+
interactive run may also exercise the launch phase.
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# Implementation reference
|
|
2
|
+
|
|
3
|
+
The reference implementation publishes two npm packages:
|
|
4
|
+
|
|
5
|
+
- **`@awebai/oats`**: runtime-neutral kernel, universal `oats` CLI,
|
|
6
|
+
bootstrap skills, instruction sources, and the official capability marketplace.
|
|
7
|
+
- **`@awebai/oats-pi`**: minimal pi adapter for instance-local resource
|
|
8
|
+
exposure and memory session events. It registers no agent tools.
|
|
9
|
+
|
|
10
|
+
Claude instances consume the generated standard files directly through the
|
|
11
|
+
instance home's `.claude/` and `CLAUDE.md` symlinks. OATS does **not** redirect
|
|
12
|
+
Claude's config home: an isolated one cannot authenticate, and the operator's
|
|
13
|
+
own Claude configuration is deliberately left enabled.
|
|
14
|
+
|
|
15
|
+
## Repository layout
|
|
16
|
+
|
|
17
|
+
| Path | Purpose |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `lib/core.mjs` | Souls, instances, config/target resolver, capability discovery, composition, locks/trust, hooks. |
|
|
20
|
+
| `bin/oats.mjs` | Agent lifecycle, config, acquisition/trust/activation, doctor, and operational command dispatch. |
|
|
21
|
+
| `capabilities/` | Bundled additive packages and layer integrations, each with `oats.json`. |
|
|
22
|
+
| `skills/` | Kernel/bootstrap and package-authoring skills. |
|
|
23
|
+
| `injects/` | Kernel and work-mode instruction sources. |
|
|
24
|
+
| `packages/pi/` | Thin pi adapter. |
|
|
25
|
+
| `packages/desktop/` | OATS Desktop — the Electron control panel and its bundled zero-dependency backend server (private, not published). |
|
|
26
|
+
| `test/` | Capability resolver/composition/security lifecycle tests. |
|
|
27
|
+
| `agents/` | The framework's own portable expert souls. |
|
|
28
|
+
|
|
29
|
+
Capability discovery has one layout: each config scope's `.agents/capabilities/` split into
|
|
30
|
+
`installed/` (acquired, locked, gitignored, restorable via bare `oats install`)
|
|
31
|
+
and `owned/` (authored at that scope, config-owned trusted; committed where
|
|
32
|
+
the scope is a git repo, plain scope-durable files elsewhere).
|
|
33
|
+
|
|
34
|
+
The live control panel is the OATS Desktop app (`packages/desktop/`): an
|
|
35
|
+
Electron shell over a bundled zero-dependency localhost server that uses
|
|
36
|
+
plain OATS metadata/files plus git and tmux; no pi APIs cross into the
|
|
37
|
+
feature, so the same surface works for pi and Claude instances. (`oats pane`
|
|
38
|
+
and the `oats.web` browser panel were retired in its favor.)
|
|
39
|
+
|
|
40
|
+
## Instance layout
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
<agents-root>/<agent>/
|
|
44
|
+
soul/
|
|
45
|
+
soul.yaml
|
|
46
|
+
AGENTS.md # canonical role instructions
|
|
47
|
+
CLAUDE.md -> AGENTS.md
|
|
48
|
+
skills/ # soul-private skills
|
|
49
|
+
instances/<instance>/
|
|
50
|
+
soul -> ../../soul
|
|
51
|
+
AGENTS.md # generated composition (regular file)
|
|
52
|
+
CLAUDE.md -> AGENTS.md
|
|
53
|
+
.agents/skills/ # exact materialized set
|
|
54
|
+
.claude/skills -> ../.agents/skills
|
|
55
|
+
work/
|
|
56
|
+
TASK.md
|
|
57
|
+
instance.json # capabilities, skills, instruction sources, lifecycle metadata
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Knowledge integration hooks may add memory files. The kernel does not assume
|
|
61
|
+
their names.
|
|
62
|
+
|
|
63
|
+
## Resolution
|
|
64
|
+
|
|
65
|
+
`configChain(context)` loads `oats-config.yaml` from closest scope outward.
|
|
66
|
+
`resolveCapabilities(context, soulName)`:
|
|
67
|
+
|
|
68
|
+
1. resolves explicit group definitions;
|
|
69
|
+
2. collects matching global/group/soul bindings;
|
|
70
|
+
3. composes settings by target specificity then config closeness;
|
|
71
|
+
4. applies explicit enable/exclusion;
|
|
72
|
+
5. validates equal-specificity conflicts, IDs, command namespaces, lock
|
|
73
|
+
integrity, and skill/layer collisions; and
|
|
74
|
+
6. returns deterministic active capability records with provenance.
|
|
75
|
+
|
|
76
|
+
`resolveOatsConfig` maps active packages declaring `layer` into the exclusive
|
|
77
|
+
knowledge/messaging/tasks slots. `layers.<layer>: none` explicitly suppresses
|
|
78
|
+
an inherited slot and remains distinct from absence.
|
|
79
|
+
|
|
80
|
+
## Spawn composition
|
|
81
|
+
|
|
82
|
+
`spawnInstance` resolves against the soul's repository and soul name. It:
|
|
83
|
+
|
|
84
|
+
0. resolves and validates WHERE the home will be created, before any side
|
|
85
|
+
effect: the destination must be the agent directory's own `instances/`
|
|
86
|
+
child, that agent directory must lie inside this deployment, and a linked
|
|
87
|
+
worktree maps to the primary checkout — otherwise `E_NO_CANONICAL_ROOT` and
|
|
88
|
+
nothing is created. The check is repeated on the created directory before
|
|
89
|
+
anything is written into it. See
|
|
90
|
+
[souls-and-instances.md](souls-and-instances.md#deployment-prerequisite-the-agents-directory-must-be-operator-owned)
|
|
91
|
+
for the deployment prerequisite this rests on;
|
|
92
|
+
1. calls `composeInstanceAgentsMd` without writing the soul;
|
|
93
|
+
2. writes generated `AGENTS.md` and canonical compatibility symlinks;
|
|
94
|
+
3. copies kernel + soul + active package skill trees into real directories in
|
|
95
|
+
one instance-local root, failing duplicate names unless `skill-overrides`
|
|
96
|
+
chooses a source;
|
|
97
|
+
4. creates the selected work topology;
|
|
98
|
+
5. runs active hooks in deterministic order; and
|
|
99
|
+
6. records capabilities, settings, trust, skill names/sources, instruction
|
|
100
|
+
files, hooks, capability metadata, and forward-only spawn lineage in
|
|
101
|
+
`instance.json`.
|
|
102
|
+
|
|
103
|
+
Pi launches with `--no-skills --skill <instance-home>/.agents/skills
|
|
104
|
+
--no-context-files --no-prompt-templates --append-system-prompt
|
|
105
|
+
<instance-home>/AGENTS.md`. The OATS-managed skill set is exactly the composed
|
|
106
|
+
one: no user, project, ancestor or package skill catalogs. It is not a claim
|
|
107
|
+
that nothing else can reach the session — extensions stay ambient (below), and
|
|
108
|
+
what they contribute stays with them.
|
|
109
|
+
|
|
110
|
+
After the canonical soul and kernel text, every generated `AGENTS.md` states the
|
|
111
|
+
runtime-neutral **home/work boundary** (`injects/instance-boundary.md`) — for
|
|
112
|
+
every work mode and for capability service agents alike — immediately before the
|
|
113
|
+
work-mode block it frames: `<instance-home>` (`$OATS_INSTANCE_HOME`) holds the
|
|
114
|
+
brain, task, provenance and working state, and is where OATS operational/lifecycle
|
|
115
|
+
commands are run from — together with the commands of whatever capabilities are
|
|
116
|
+
active, `aw` among them when aweb messaging is — since they resolve scope from
|
|
117
|
+
the working directory (`--dir <path>` reaches another deliberately); the home's
|
|
118
|
+
`soul` link is to be treated as read-only because writes through it bypass the
|
|
119
|
+
branch and review path; and `<instance-home>/work` is the repository or workspace
|
|
120
|
+
view where repository reading, editing, building, testing, git and commits
|
|
121
|
+
happen. It bounds *repository* work rather than forbidding all output elsewhere —
|
|
122
|
+
episodic state lives in the home, and a service agent's own artifacts (a report
|
|
123
|
+
written to a temp file before mailing it) are its role's business. What each mode
|
|
124
|
+
actually permits is the work-mode block's call, which follows immediately.
|
|
125
|
+
|
|
126
|
+
`--no-context-files` also suppresses the instance's *own* composed `AGENTS.md`,
|
|
127
|
+
so that is delivered explicitly; the work tree's `AGENTS.md` stays readable by
|
|
128
|
+
the file tools — readable, not auto-injected.
|
|
129
|
+
|
|
130
|
+
Pi **extensions stay ambient**: operators run cross-agent extensions (web
|
|
131
|
+
search, output formatting) that every instance should keep, so OATS does not
|
|
132
|
+
pass `--no-extensions`. The accepted residue is narrow but real — an
|
|
133
|
+
extension's `resources_discover` hook can contribute skill paths that survive
|
|
134
|
+
`--no-skills`. Today only the OATS bridge does that, and inside an instance it
|
|
135
|
+
contributes that instance's own `.agents/skills`, leaving the composed set
|
|
136
|
+
unchanged.
|
|
137
|
+
|
|
138
|
+
Runtime packages that active capabilities declare (see
|
|
139
|
+
[capabilities](capabilities.md)) are verified at spawn and recorded in
|
|
140
|
+
`instance.json`; a missing one fails the spawn with the consent command to fix
|
|
141
|
+
it, rather than starting an agent whose instructions promise a capability it
|
|
142
|
+
does not have. OATS does not resolve their extension entry points — pi owns that
|
|
143
|
+
resolution, including globs and conventional directories.
|
|
144
|
+
|
|
145
|
+
Claude discovers the same set natively through the instance's `.claude/skills`
|
|
146
|
+
symlink, and its composed instructions through `CLAUDE.md -> AGENTS.md`.
|
|
147
|
+
|
|
148
|
+
Claude Code's **own configuration stays enabled**: user and project skills,
|
|
149
|
+
plugins, settings and `CLAUDE.md` all resolve into an OATS session as they
|
|
150
|
+
normally would. That is a deliberate product choice — those mechanisms are
|
|
151
|
+
powerful and the operator decides whether to use them; a deployment that wants
|
|
152
|
+
only the OATS-composed surface achieves it by configuring everything OATS-side.
|
|
153
|
+
So OATS passes no `--setting-sources`, no exclusions, and no synthetic plugin.
|
|
154
|
+
|
|
155
|
+
Measured behavior worth knowing when reasoning about an instance: project
|
|
156
|
+
skills resolve from the working directory up to the **repository root**, so an
|
|
157
|
+
instance homed inside a repository with its own `.claude/skills` sees those
|
|
158
|
+
too. Project *settings* — hooks, plugins, permissions, custom agents — resolve
|
|
159
|
+
from the instance home rather than from ancestors.
|
|
160
|
+
|
|
161
|
+
Both runtimes record what they actually expose in `instance.json` under
|
|
162
|
+
`composition.materialized.runtimePosture`: the OATS-composed set, what is
|
|
163
|
+
curtailed, and what remains ambient. The deviation from strict composition is
|
|
164
|
+
auditable rather than implied.
|
|
165
|
+
|
|
166
|
+
## Instructions
|
|
167
|
+
|
|
168
|
+
The generated order is:
|
|
169
|
+
|
|
170
|
+
1. canonical soul content;
|
|
171
|
+
2. kernel OATS block;
|
|
172
|
+
3. local-soul block (local souls only);
|
|
173
|
+
4. **home/work boundary block** — runtime-neutral, every mode and every kind;
|
|
174
|
+
5. actual spawn work-mode block;
|
|
175
|
+
6. active capability blocks in resolver order; and
|
|
176
|
+
7. unconditional config blocks outermost to innermost.
|
|
177
|
+
|
|
178
|
+
Every generated block carries its source path. `oats doctor --soul <name>` uses
|
|
179
|
+
the same composer and prints/returns the final text. Config-dependent prose is
|
|
180
|
+
never reconciled into committed souls.
|
|
181
|
+
|
|
182
|
+
## Acquisition and trust
|
|
183
|
+
|
|
184
|
+
External installation copies/clones one exact artifact and writes
|
|
185
|
+
`oats-lock.json` with source, version/commit, and SHA-256 tree integrity. An
|
|
186
|
+
existing destination is never pulled silently. Resolution rejects changed
|
|
187
|
+
locked artifacts and unlocked installed/path packages.
|
|
188
|
+
|
|
189
|
+
Executable package hooks, commands, and launch-environment authority are omitted
|
|
190
|
+
until `oats trust <id>` marks the exact locked integrity approved. Bundled
|
|
191
|
+
packages are framework-trusted.
|
|
192
|
+
Packages under a scope's `owned/` subtree are config-owned. Anything under
|
|
193
|
+
`installed/` requires a matching lock entry, so an acquired artifact cannot
|
|
194
|
+
bypass executable trust by its directory location.
|
|
195
|
+
|
|
196
|
+
Distribution packages generalize this: a package materializes each capability it
|
|
197
|
+
exports into `.agents/capabilities/installed/<id>/`, each independently
|
|
198
|
+
addressable and independently trusted at its own artifact integrity. There is no
|
|
199
|
+
persistent package store. The `lockfileVersion: 2` lock records package
|
|
200
|
+
provenance (`packages`) and materialized capability identity (`capabilities`)
|
|
201
|
+
separately. See `docs/design/package-engine-contract.md` for the resolver/lock
|
|
202
|
+
API and error taxonomy.
|
|
203
|
+
|
|
204
|
+
## Hooks and scaffold ownership
|
|
205
|
+
|
|
206
|
+
Only `soul-scaffold`, `spawn`, and `retire` manifest hooks are accepted.
|
|
207
|
+
Spawn/scaffold use outer-scope then capability-ID order; retire reverses it.
|
|
208
|
+
Each hook receives package identity/layer plus structured OATS environment and
|
|
209
|
+
may emit a final JSON object containing `meta`, `brief`, `warning`, or `launch`.
|
|
210
|
+
Only a spawn hook may add `env`; other lifecycle events reject it rather than
|
|
211
|
+
silently discard it. Launch environment is string-only,
|
|
212
|
+
size/control-character checked, owned by an unambiguous dotted capability
|
|
213
|
+
vendor, and restricted to the manifest's exact trust-visible `environment`
|
|
214
|
+
declaration. Capabilities that request this authority must use the stricter
|
|
215
|
+
dotted ID form even though capabilities without environment authority retain
|
|
216
|
+
the wider namespaced-ID compatibility contract. Explicit and automatic trust
|
|
217
|
+
disclose the declaration before persisting authority. Known process-bootstrap
|
|
218
|
+
names are denied in depth, not treated as an
|
|
219
|
+
exhaustive authority list. Aggregation is deterministic, shell-quoted, and
|
|
220
|
+
collision-fatal. It prefixes only the initial runtime command;
|
|
221
|
+
values are persisted with that command, so the contract is for non-secret
|
|
222
|
+
locators and broker endpoints, never bearer credentials or durable principal
|
|
223
|
+
root keys. No restart/replay contract exists. A fatal environment contract error enters
|
|
224
|
+
the required-spawn rollback transaction. It runs compensation in reverse,
|
|
225
|
+
removes and verifies rollback-owned Git topology, and removes the home only
|
|
226
|
+
when cleanup completed. Failed compensation or reported state with no retire
|
|
227
|
+
hook uses the same retryable quarantine as every other incomplete spawn.
|
|
228
|
+
|
|
229
|
+
Soul scaffolding snapshots files around each package hook and records new-file
|
|
230
|
+
ownership in `.oats-scaffold-owners.json`. Overwriting canonical or another
|
|
231
|
+
package's file restores the prior bytes and raises a conflict.
|
|
232
|
+
|
|
233
|
+
## Commands
|
|
234
|
+
|
|
235
|
+
Kernel/package-management commands are always available. Operational
|
|
236
|
+
namespaces are discovered from manifest `command`, but dispatch verifies that
|
|
237
|
+
`instance.json` or current soul resolution contains the package and that its
|
|
238
|
+
locked executable surface is trusted.
|
|
239
|
+
|
|
240
|
+
## Verification
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
npm test
|
|
244
|
+
npm run check
|
|
245
|
+
npm run check:pi
|
|
246
|
+
npm run validate
|
|
247
|
+
npm run validate:okf
|
|
248
|
+
npm run pack:check
|
|
249
|
+
npm run smoke:tarball
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Pull-request CI runs this matrix on supported Node 22. `validate` compiles both
|
|
253
|
+
public JSON schemas, validates clean-contract manifests, parses documented
|
|
254
|
+
OATS config examples with the production parser, and checks maintainable public
|
|
255
|
+
local links/anchors. `pack:check` dry-runs both npm packages and rejects missing
|
|
256
|
+
runtime surfaces or leaked workspace/test state.
|
|
257
|
+
|
|
258
|
+
The clean-room smoke test packs both packages, installs their tarballs outside
|
|
259
|
+
the checkout, verifies the adapter resolves that installed kernel, runs
|
|
260
|
+
`init`/`doctor`, and creates/retires a clean-contract scaffold while checking
|
|
261
|
+
exact skills, generated instructions, canonical soul immutability, and
|
|
262
|
+
metadata.
|
|
263
|
+
|
|
264
|
+
One manual probe is required after every release and before 0.19.0 ships: from
|
|
265
|
+
the **published** kernel (not a checkout), install `oats.authoring` into a fresh
|
|
266
|
+
scope, activate it for a framework-author soul, and spawn that soul. The spawn
|
|
267
|
+
must succeed with `integration-authoring`, `skill-craft`, and `soul-craft`
|
|
268
|
+
materialized in the instance's `.agents/skills/`. Framework-hoisted resources
|
|
269
|
+
are resolved by path arithmetic against the installed kernel's own layout, so a
|
|
270
|
+
source-tree run can pass while every installed deployment fails.
|
|
271
|
+
|
|
272
|
+
These deterministic checks deliberately do **not** contact real aweb, Jira, or
|
|
273
|
+
Linear services, validate remote git hosting/auth flows, or publish npm
|
|
274
|
+
artifacts. Adapter/discovery changes additionally require a disposable real pi
|
|
275
|
+
session from the packed artifacts; external services remain credentialed,
|
|
276
|
+
out-of-scope probes. Release CI publishes both
|
|
277
|
+
packages from one tag; keep versions synchronized because exact pi isolation
|
|
278
|
+
depends on both kernel launch and adapter discovery behavior.
|
|
279
|
+
|
|
280
|
+
Runtime-neutral token/cost/model/tool telemetry for Control Pane remains a
|
|
281
|
+
follow-up; it requires an adapter-neutral event contract rather than pi-specific
|
|
282
|
+
inspection in the universal CLI.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Integrations
|
|
2
|
+
|
|
3
|
+
An **integration is a capability package selected to satisfy one exclusive
|
|
4
|
+
fundamental layer**: knowledge, messaging, or tasks. The layer model remains a
|
|
5
|
+
formal part of OATS; capability packages generalize how its implementations and
|
|
6
|
+
other reusable agent features are distributed and targeted.
|
|
7
|
+
|
|
8
|
+
Read [Capability packages](capabilities.md) first for manifests, acquisition,
|
|
9
|
+
targeting, instance-local composition, locks, trust, hooks, and commands.
|
|
10
|
+
|
|
11
|
+
## Fundamental-layer contract
|
|
12
|
+
|
|
13
|
+
For each soul, OATS resolves zero or one implementation for each pluggable
|
|
14
|
+
layer:
|
|
15
|
+
|
|
16
|
+
| Layer | Contract | Bundled choices |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| knowledge | capture, durable knowledge form, and promotion lifecycle | `oats.okf` |
|
|
19
|
+
| messaging | reachable instance identity and human/agent communication | `oats.aweb` |
|
|
20
|
+
| tasks | durable work queue, ownership, and status | `oats.jira`, `oats.linear` |
|
|
21
|
+
|
|
22
|
+
A capability manifest becomes an integration by declaring one `layer`. It may
|
|
23
|
+
not declare several layers. Two active packages for the same layer are a
|
|
24
|
+
configuration error; general capabilities without `layer` remain additive.
|
|
25
|
+
|
|
26
|
+
This exclusivity matters. For example, task state belongs to the selected task
|
|
27
|
+
integration even if a messaging tool also happens to offer task features.
|
|
28
|
+
|
|
29
|
+
## Selecting an integration
|
|
30
|
+
|
|
31
|
+
New config activates the package for the intended target:
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
agent-types:
|
|
35
|
+
product-agents:
|
|
36
|
+
description: Planner/developer/reviewer souls (they declare `type: product-agents`)
|
|
37
|
+
|
|
38
|
+
capabilities:
|
|
39
|
+
layers:
|
|
40
|
+
knowledge:
|
|
41
|
+
capability: oats.okf
|
|
42
|
+
from: installed
|
|
43
|
+
messaging:
|
|
44
|
+
capability: oats.aweb
|
|
45
|
+
from: installed
|
|
46
|
+
agent-types:
|
|
47
|
+
product-agents:
|
|
48
|
+
enabled: true
|
|
49
|
+
settings:
|
|
50
|
+
team: example-team
|
|
51
|
+
tasks:
|
|
52
|
+
capability: oats.linear
|
|
53
|
+
from: installed
|
|
54
|
+
agent-types:
|
|
55
|
+
product-agents:
|
|
56
|
+
enabled: true
|
|
57
|
+
settings:
|
|
58
|
+
team: ENG
|
|
59
|
+
project: Agent Platform
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Every matching soul gets one knowledge, messaging, and tasks implementation.
|
|
63
|
+
A non-matching soul can resolve a different integration or leave a layer
|
|
64
|
+
unresolved.
|
|
65
|
+
|
|
66
|
+
CLI equivalents:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
oats use oats.okf --global
|
|
70
|
+
oats use oats.aweb --type product-agents
|
|
71
|
+
oats use oats.linear --type product-agents
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The manifest-declared layer makes a separate CLI/config layer selection
|
|
75
|
+
unnecessary — `oats use` writes the entry under `capabilities.layers.<layer>`.
|
|
76
|
+
To leave an inherited layer deliberately unfilled, use
|
|
77
|
+
`oats use none --layer <layer>` (writes `capabilities.layers.<layer>: none`).
|
|
78
|
+
|
|
79
|
+
## Bundled integrations
|
|
80
|
+
|
|
81
|
+
### `oats.okf`
|
|
82
|
+
|
|
83
|
+
The knowledge integration creates OKF soul bundles, instance `STATE.md`,
|
|
84
|
+
`log.md`, and `notes/`, and exposes the `okf` and `memory-harvest` skills. The
|
|
85
|
+
instance-triggered `oats okf harvest` command promotes pending notes after a
|
|
86
|
+
commit. Its scaffold/spawn hooks own memory mechanics; the kernel remains
|
|
87
|
+
knowledge-format agnostic.
|
|
88
|
+
|
|
89
|
+
### `oats.aweb`
|
|
90
|
+
|
|
91
|
+
The messaging integration mints an instance identity at spawn, removes it at
|
|
92
|
+
retire, and contributes official aweb messaging/team skills. It requires the
|
|
93
|
+
`aw` CLI. Messaging does not become the task system.
|
|
94
|
+
|
|
95
|
+
### `oats.jira`
|
|
96
|
+
|
|
97
|
+
The Jira tasks integration contributes the `jira-tasks` protocol and an
|
|
98
|
+
advisory spawn hook. It requires `acli`; settings commonly include `site` and
|
|
99
|
+
`project`.
|
|
100
|
+
|
|
101
|
+
### `oats.linear`
|
|
102
|
+
|
|
103
|
+
The Linear tasks integration contributes JSON-first `oats linear` commands,
|
|
104
|
+
the `linear-tasks` skill, and an advisory spawn hook. It uses
|
|
105
|
+
`LINEAR_API_KEY`; secrets never belong in OATS config. See
|
|
106
|
+
`capabilities/oats-linear/README.md` for its support boundary.
|
|
107
|
+
|
|
108
|
+
> **Removed: `oats.web`.** The browser web-panel capability was retired in
|
|
109
|
+
> favor of the OATS Desktop app (`packages/desktop/`), which bundles the same
|
|
110
|
+
> zero-dependency loopback server. If an `oats-lock.json` or `oats-config.yaml`
|
|
111
|
+
> still names `oats.web`, remove that entry — the capability no longer exists
|
|
112
|
+
> in the marketplace. Full migration steps: [docs/desktop-succession.md](desktop-succession.md).
|
|
113
|
+
|
|
114
|
+
## Build an integration
|
|
115
|
+
|
|
116
|
+
Use a namespaced capability manifest with exactly one `layer`, then test it as
|
|
117
|
+
a capability package. The framework's `integrations-expert` soul remains the
|
|
118
|
+
specialist for layer contract design. The `integration-authoring` skill routes
|
|
119
|
+
work to it, while the package itself lives under `capabilities/` or
|
|
120
|
+
`.agents/capabilities/`.
|
|
121
|
+
|
|
122
|
+
Do not put target soul names in the manifest. Acquisition, agent types,
|
|
123
|
+
activation, settings, exclusions, and overrides belong to `oats-config.yaml`.
|