@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.
Files changed (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +380 -0
  3. package/bin/oats.mjs +3294 -0
  4. package/capabilities/oats-authoring/oats.json +12 -0
  5. package/capabilities/oats-aweb/bin/oats-aweb.mjs +297 -0
  6. package/capabilities/oats-aweb/injects/aweb.md +55 -0
  7. package/capabilities/oats-aweb/oats.json +47 -0
  8. package/capabilities/oats-aweb/package.json +20 -0
  9. package/capabilities/oats-jira/bin/oats-jira.mjs +40 -0
  10. package/capabilities/oats-jira/injects/jira.md +10 -0
  11. package/capabilities/oats-jira/oats.json +22 -0
  12. package/capabilities/oats-jira/package.json +25 -0
  13. package/capabilities/oats-jira/skills/jira-tasks/SKILL.md +176 -0
  14. package/capabilities/oats-linear/README.md +234 -0
  15. package/capabilities/oats-linear/bin/oats-linear-hook.mjs +32 -0
  16. package/capabilities/oats-linear/bin/oats-linear.mjs +344 -0
  17. package/capabilities/oats-linear/injects/linear.md +8 -0
  18. package/capabilities/oats-linear/oats.json +24 -0
  19. package/capabilities/oats-linear/package.json +29 -0
  20. package/capabilities/oats-linear/skills/linear-tasks/SKILL.md +217 -0
  21. package/capabilities/oats-linear/test/oats-linear.test.mjs +168 -0
  22. package/capabilities/oats-okf/agents/memory-harvest.md +25 -0
  23. package/capabilities/oats-okf/bin/oats-okf.mjs +283 -0
  24. package/capabilities/oats-okf/injects/okf.md +62 -0
  25. package/capabilities/oats-okf/oats.json +20 -0
  26. package/capabilities/oats-okf/package.json +22 -0
  27. package/capabilities/oats-okf/skills/memory-harvest/SKILL.md +100 -0
  28. package/capabilities/oats-okf/skills/okf/SKILL.md +107 -0
  29. package/capabilities/oats-okf/skills/okf/scripts/okf-validate.mjs +123 -0
  30. package/capabilities/oats-review/agents/reviewer/AGENTS.md +53 -0
  31. package/capabilities/oats-review/agents/reviewer/soul.yaml +6 -0
  32. package/capabilities/oats-review/injects/review.md +68 -0
  33. package/capabilities/oats-review/oats.json +10 -0
  34. package/capabilities/oats-review/skills/code-review/SKILL.md +44 -0
  35. package/capabilities/oats-review/skills/security-review/SKILL.md +59 -0
  36. package/docs/capabilities.md +505 -0
  37. package/docs/capability-manifest.schema.json +223 -0
  38. package/docs/configuration.md +482 -0
  39. package/docs/conventions.md +73 -0
  40. package/docs/design/desktop-ux-plan.md +362 -0
  41. package/docs/design/package-engine-contract.md +813 -0
  42. package/docs/design/package-runtime-api.md +414 -0
  43. package/docs/desktop-cli-api.md +89 -0
  44. package/docs/desktop-succession.md +51 -0
  45. package/docs/desktop.md +187 -0
  46. package/docs/implementation.md +282 -0
  47. package/docs/integrations.md +123 -0
  48. package/docs/knowledge-theory.md +97 -0
  49. package/docs/knowledge.md +139 -0
  50. package/docs/layers.md +110 -0
  51. package/docs/migration-from-oas.md +122 -0
  52. package/docs/oats-config.schema.json +140 -0
  53. package/docs/oats-lock.schema.json +175 -0
  54. package/docs/oats-package.schema.json +129 -0
  55. package/docs/packages.md +442 -0
  56. package/docs/release-lane.md +132 -0
  57. package/docs/release-notes/v0.18.2.md +79 -0
  58. package/docs/release-notes/v0.18.3.md +63 -0
  59. package/docs/release-notes/v0.18.4.md +65 -0
  60. package/docs/release-notes/v0.18.5.md +66 -0
  61. package/docs/release-notes/v0.18.6.md +87 -0
  62. package/docs/release-notes/v0.19.0.md +186 -0
  63. package/docs/release-notes/v0.19.1.md +24 -0
  64. package/docs/release-notes/v0.19.2.md +32 -0
  65. package/docs/release-notes/v0.19.3.md +16 -0
  66. package/docs/release-notes/v0.19.4.md +12 -0
  67. package/docs/release-notes/v0.20.0.md +89 -0
  68. package/docs/release-notes/v0.22.0.md +180 -0
  69. package/docs/souls-and-instances.md +344 -0
  70. package/injects/framework-workspace.md +7 -0
  71. package/injects/instance-boundary.md +43 -0
  72. package/injects/local-soul.md +19 -0
  73. package/injects/oats.md +11 -0
  74. package/injects/work-attached.md +16 -0
  75. package/injects/work-checkout.md +12 -0
  76. package/injects/work-workspace.md +22 -0
  77. package/injects/work-worktree.md +13 -0
  78. package/lib/core.mjs +6792 -0
  79. package/lib/packages.mjs +1375 -0
  80. package/lib/tmux-config.mjs +35 -0
  81. package/package-catalog.json +44 -0
  82. package/package.json +55 -0
  83. package/packages/record/README.md +151 -0
  84. package/packages/record/bin/capture.mjs +256 -0
  85. package/packages/record/bin/recall.mjs +102 -0
  86. package/packages/record/bin/setup.mjs +281 -0
  87. package/packages/record/bin/turn-record.mjs +47 -0
  88. package/packages/record/docs/turn-record-sot.md +350 -0
  89. package/packages/record/lib/canonical.mjs +151 -0
  90. package/packages/record/lib/capture-aw.mjs +179 -0
  91. package/packages/record/lib/capture-cc.mjs +322 -0
  92. package/packages/record/lib/formats.mjs +296 -0
  93. package/packages/record/lib/ignore.mjs +155 -0
  94. package/packages/record/lib/index-db.mjs +524 -0
  95. package/packages/record/lib/project-aweb.mjs +251 -0
  96. package/packages/record/lib/segments.mjs +186 -0
  97. package/packages/record/lib/store.mjs +447 -0
  98. package/packages/record/lib/tags.mjs +114 -0
  99. package/packages/record/package.json +45 -0
  100. package/packages/record/test/vectors/README.md +34 -0
  101. package/packages/record/test/vectors/aweb-projection-v1.json +231 -0
  102. package/packages/record/test/vectors/journal-merge-v1.json +261 -0
  103. package/packages/record/test/vectors/turn-id-v1.json +152 -0
  104. package/packages/record/test/vectors/validate.mjs +391 -0
  105. package/skills/integration-authoring/SKILL.md +76 -0
  106. package/skills/oats/SKILL.md +151 -0
  107. package/skills/oats-config/SKILL.md +162 -0
  108. package/skills/oats-getting-started/SKILL.md +159 -0
  109. package/skills/oats-packages/SKILL.md +180 -0
  110. package/skills/oats-support/SKILL.md +79 -0
  111. package/skills/skill-craft/SKILL.md +109 -0
  112. package/skills/soul-craft/SKILL.md +109 -0
@@ -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`.