@awebai/oats 0.22.0 → 0.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +40 -50
  2. package/bin/oats.mjs +242 -22
  3. package/capabilities/oats-authoring/LICENSE +21 -0
  4. package/capabilities/oats-authoring/oats-package.json +11 -0
  5. package/capabilities/oats-authoring/oats.json +4 -4
  6. package/capabilities/oats-authoring/skills/integration-authoring/SKILL.md +63 -0
  7. package/capabilities/oats-authoring/skills/skill-craft/SKILL.md +109 -0
  8. package/capabilities/oats-authoring/skills/soul-craft/SKILL.md +109 -0
  9. package/capabilities/oats-aweb/injects/aweb.md +4 -3
  10. package/capabilities/oats-aweb/oats.json +7 -7
  11. package/capabilities/oats-aweb/skills/LICENSE +21 -0
  12. package/capabilities/oats-aweb/skills/VENDORED.md +26 -0
  13. package/capabilities/oats-aweb/skills/aweb-identity/SKILL.md +201 -0
  14. package/capabilities/oats-aweb/skills/aweb-messaging/SKILL.md +161 -0
  15. package/capabilities/oats-aweb/skills/aweb-messaging/references/messaging-scenarios.md +61 -0
  16. package/capabilities/oats-aweb/skills/aweb-team-membership/SKILL.md +328 -0
  17. package/capabilities/oats-aweb/skills/aweb-team-membership/references/team-membership-reference.md +74 -0
  18. package/capabilities/oats-jira/oats.json +1 -1
  19. package/capabilities/oats-linear/oats.json +1 -1
  20. package/capabilities/oats-okf/agents/{memory-harvest.md → memory-harvest/AGENTS.md} +3 -1
  21. package/capabilities/oats-okf/agents/memory-harvest/soul.yaml +6 -0
  22. package/capabilities/oats-okf/bin/oats-okf.mjs +201 -54
  23. package/capabilities/oats-okf/injects/okf.md +7 -0
  24. package/capabilities/oats-okf/oats.json +5 -2
  25. package/capabilities/oats-okf/skills/memory-harvest/SKILL.md +42 -1
  26. package/capabilities/oats-review/oats.json +1 -1
  27. package/docs/2026-09-03-architecture-proposal.md +642 -0
  28. package/docs/execution-targets.md +181 -0
  29. package/docs/first-team-demo.md +87 -0
  30. package/docs/first-team.md +179 -0
  31. package/docs/implementation.md +14 -1
  32. package/docs/integrations.md +83 -65
  33. package/docs/layers.md +356 -80
  34. package/docs/migration-from-oas.md +80 -116
  35. package/docs/oats-config.schema.json +1 -0
  36. package/docs/operating-team-migration.md +217 -0
  37. package/docs/release-notes/v0.22.1.md +106 -0
  38. package/docs/release-notes/v0.22.2.md +69 -0
  39. package/docs/servers.md +94 -0
  40. package/docs/souls-and-instances.md +30 -3
  41. package/lib/core.mjs +626 -415
  42. package/lib/herdr.mjs +95 -0
  43. package/lib/servers.mjs +436 -0
  44. package/lib/session-input.mjs +78 -0
  45. package/lib/session-viewer.mjs +51 -0
  46. package/package-catalog.json +2 -2
  47. package/package.json +1 -1
  48. package/packages/record/README.md +76 -16
  49. package/packages/record/bin/capture.mjs +59 -3
  50. package/packages/record/bin/recall.mjs +67 -1
  51. package/packages/record/docs/turn-record-sot.md +1 -1
  52. package/packages/record/lib/sessions-for-home.mjs +130 -0
  53. package/packages/record/lib/store.mjs +207 -43
  54. package/skills/oats/SKILL.md +6 -2
  55. package/capabilities/oats-aweb/package.json +0 -20
  56. package/capabilities/oats-jira/package.json +0 -25
  57. package/capabilities/oats-linear/README.md +0 -234
  58. package/capabilities/oats-linear/package.json +0 -29
  59. package/capabilities/oats-linear/test/oats-linear.test.mjs +0 -168
  60. package/capabilities/oats-okf/package.json +0 -22
@@ -0,0 +1,181 @@
1
+ # Execution targets and shared wake delivery
2
+
3
+ Implementation agreement, 2026-09-05. Lead owns native runtime launch,
4
+ local tmux/Herdr adapters and terminal input; oats owns server registration,
5
+ remote CLI routing and Desktop target selection. Aweb owns the event listener,
6
+ notification state and delivery policy through OATS terminal input. This is the implementation
7
+ contract, not a claim that these features have shipped.
8
+
9
+ OATS manages composition, worktrees, capability lifecycle and retirement on the execution
10
+ host. A session backend manages the persistent terminal. Desktop is a client;
11
+ closing it must stop neither the agent nor notification delivery.
12
+
13
+ ```mermaid
14
+ flowchart LR
15
+ UI[Desktop] --> CLI[OATS CLI]
16
+ CLI --> Local[Local OATS]
17
+ CLI --> SSH[OpenSSH]
18
+ SSH --> Remote[Remote OATS]
19
+ Local --> Sessions[tmux or Herdr]
20
+ Remote --> RemoteSessions[tmux or Herdr]
21
+ Events[aweb SSE] --> Wake[aweb wake service on execution host]
22
+ Wake --> Local
23
+ RemoteWake[aweb wake service on remote host] --> Remote
24
+ ```
25
+
26
+ Server registrations live in the operator's machine configuration, outside
27
+ repository configuration. Each entry has an id, label, OpenSSH host alias,
28
+ absolute workspace path and OATS/Herdr executable paths. SSH owns key selection,
29
+ host verification and authentication. Registration stores no private keys.
30
+ Remote lifecycle calls invoke the remote installed OATS CLI with argument-safe
31
+ quoting and the same JSON envelope as local calls. Version/envelope compatibility
32
+ is checked before mutation. Repository operations always run on that host.
33
+
34
+ The local representation of a remote instance snapshots its route:
35
+
36
+ ```json
37
+ {
38
+ "serverId": "build-server",
39
+ "target": {
40
+ "sshHost": "build-server",
41
+ "workspace": "/srv/team",
42
+ "oatsPath": "/usr/local/bin/oats",
43
+ "herdrPath": "/usr/local/bin/herdr"
44
+ },
45
+ "instance": "developer-fix",
46
+ "home": "/srv/team/agents/developer/instances/developer-fix"
47
+ }
48
+ ```
49
+
50
+ `serverId` is for display. Later inspect/retire operations use the snapshot,
51
+ never silently resolve a changed registry entry. A local cache is not authority
52
+ for the remote instance's state. Remote status is pulled from its owning kernel.
53
+
54
+ The host's instance and independent retirement baseline retain the same local
55
+ session receipt. Existing `tmux: {session, window, socket}` remains readable.
56
+ New Herdr instances use:
57
+
58
+ ```json
59
+ {
60
+ "backend": "herdr",
61
+ "binary": "/usr/local/bin/herdr",
62
+ "socket": "/home/operator/.config/herdr/sessions/oats/herdr.sock",
63
+ "workspaceId": "w1",
64
+ "paneId": "w1:p1",
65
+ "terminalId": "term_65ab9108c6c301",
66
+ "protocol": 20
67
+ }
68
+ ```
69
+
70
+ The terminal id distinguishes a replacement occupant after a server restart.
71
+ Backend operations allocate, start, inspect, stop and attach a viewer. Retirement
72
+ compares the receipt with its baseline and proves the original session absent.
73
+ An unavailable server or failed inspection is not proof of absence. The same
74
+ rule applies to spawn compensation and detached self-retirement. Lifecycle
75
+ operations run on the target host, so the local backend does not implement SSH.
76
+
77
+ Herdr 0.8.2 exposes snapshots, socket commands, agent-state inspection and JSONL
78
+ terminal observation/control. Its protocol is versioned. Agent prompts reject
79
+ approval-blocked agents, but prompting a working agent does not prove the new
80
+ message was processed. The adapter must retain this distinction. See the
81
+ [Herdr socket API](https://herdr.dev/docs/socket-api/) and
82
+ [remote connections](https://herdr.dev/docs/persistence-remote/).
83
+
84
+ An aweb host service owns event streams for managed instances; the GUI displays
85
+ and controls it. Reuse aweb's existing authenticated event/run loop rather than copying credential
86
+ and SSE parsing into OATS or Desktop. OATS exposes backend-neutral session
87
+ inspection and literal terminal input; aweb supplies delivery policy. Current authorization is
88
+ per identity: one long-lived stream per active identity, coalesced per instance,
89
+ with bounded retries. A single team stream requires an explicit server API.
90
+ Reconnect also checks pending state so a lost edge does not strand unread work.
91
+
92
+ Delivery is a fixed instruction to check `aw` mail/chat from the instance home,
93
+ not arbitrary sender content typed into a shell. The service never acknowledges
94
+ mail or chat on the agent's behalf. Aweb pending hints survive reconnect and service
95
+ restart, coalesce while busy and defer at approval prompts. A stopped harness,
96
+ an unknown occupant or a fallback shell is not a delivery target. Do not call a
97
+ successful terminal write an agent acknowledgement.
98
+
99
+ Native channels remain selectable during qualification; session delivery must
100
+ be exclusive with them for each instance. Removal follows real tests of Pi,
101
+ Claude and Codex receiving mail/chat, a busy turn, an approval prompt, reconnect,
102
+ service restart, GUI closure and a stopped runtime. The OATS Pi tool extension
103
+ and the aweb Pi channel are separate packages; replacing notification transport
104
+ does not silently remove unrelated tools.
105
+
106
+ Acceptance includes local CLI/Desktop spawn, reattach, preserved work and
107
+ retirement through both backends; then the same operations on a user-designated
108
+ SSH target. Registering a host without a successful remote agent run does not
109
+ qualify remote support.
110
+
111
+ ## Session CLI contract
112
+
113
+ Run on the execution host:
114
+
115
+ ```sh
116
+ oats session attach --home /absolute/instance
117
+ oats session inspect --home /absolute/instance --json
118
+ oats session input --home /absolute/instance --text-file /path/to/message --json
119
+ printf '%s' 'Check your pending work.' | oats session input --home /absolute/instance --json
120
+ ```
121
+
122
+ `attach` is interactive and does not accept `--json`. It validates the saved
123
+ endpoint on the execution host, then opens a Herdr terminal viewer or an
124
+ isolated tmux session linked to that agent's window alone. Closing its terminal
125
+ cleans the viewer without stopping the agent; retiring the agent ends the viewer
126
+ instead of switching it to a sibling. This host-local command is also the
127
+ remote Desktop attachment seam over an SSH PTY.
128
+
129
+ Input accepts UTF-8 text up to 256 KiB, with no NUL bytes. The CLI uses the
130
+ independent lifecycle receipt and refuses metadata disagreement. Tmux uses
131
+ literal bracketed paste followed by Enter. Herdr uses pane input followed by
132
+ Enter. Neither path interprets message text as a shell command. A fallback
133
+ shell or ambiguous split tmux window refuses automatic input.
134
+
135
+ Success uses the existing envelope:
136
+
137
+ ```json
138
+ {"schemaVersion":1,"ok":true,"result":{"home":"/absolute/instance","backend":"herdr","present":true,"state":"idle","submitted":true}}
139
+ ```
140
+
141
+ Inspect omits `submitted`; optional backend identifiers describe the observed
142
+ terminal. `state` is the Herdr agent state when available, `unknown` for a live
143
+ unclassified harness, `shell` for a fallback shell, `stopped` for an absent/dead
144
+ terminal, or `not-launched`. Errors use `ok:false,error:{code,message}` and a
145
+ nonzero exit. An unavailable backend is an error, never a stopped result.
146
+ Tmux receipts identify socket/session/window; automatic input requires one live
147
+ pane in that exact window. Herdr additionally verifies the original terminal ID.
148
+ The broker owns busy/approval policy and must not interpret `submitted` as
149
+ processing acknowledgement.
150
+
151
+ Capability spawn hooks register a pending home before runtime allocation;
152
+ inspection becomes available once its receipt is persisted. Retire hooks
153
+ unregister after quiescence. The broker must tolerate this lifecycle order and
154
+ missing homes, and persist pending hints until handled. Kernel session operations
155
+ contain no aweb identity, credentials, stream or notification logic.
156
+
157
+ The portable integration belongs to the official `oats.aweb` capability.
158
+ The aweb development deployment currently selects its owned `aweb.identity`
159
+ capability; that deployment-specific choice does not change the broker interface
160
+ and needs equivalent registration glue when switched to session delivery.
161
+
162
+ ## Shared permission setting
163
+
164
+ Set `yolo: true` in an `oats-config.yaml` to apply it to that scope. The closest
165
+ scope wins; an optional `yolo` in soul.yaml overrides it; `oats spawn --yolo` or
166
+ `--no-yolo` overrides both. `oats create` accepts those flags too. Desktop offers
167
+ the same per-launch choice. With no setting, native policy is retained.
168
+
169
+ Codex receives `--yolo` plus a launch-local trust setting for the generated
170
+ instance home; Claude receives `--dangerously-skip-permissions`. Pi's existing
171
+ project trust behavior is unchanged. `--no-yolo` removes the OATS bypass flags;
172
+ it leaves the operator's native harness settings in force. Instance metadata
173
+ records an explicitly resolved setting. This choice applies when starting an
174
+ agent, not retroactively to running sessions.
175
+
176
+ Desktop remote terminal requests contain only the server id and instance name.
177
+ The selected installed CLI resolves the saved route and performs remote
178
+ inspection before attaching over SSH. Pending inspections share the terminal
179
+ resource limit and duplicate requests share one inspection. Remote status and
180
+ instance keys must include the server so identical paths on different hosts
181
+ remain distinct.
@@ -0,0 +1,87 @@
1
+ # First-team example: OATS working on OATS
2
+
3
+ On 2026-09-05 we installed the published OATS artifacts and used Pi and
4
+ Claude Code workers to fix issues found during a fresh review. The first
5
+ team's work was release preparation in this repository.
6
+
7
+ ## The setup
8
+
9
+ | Component | Qualified value |
10
+ | --- | --- |
11
+ | Kernel and Pi adapter | 0.22.0, installed from npm |
12
+ | Workspace config | `oats.dev` 1.0.0 default, adopted at the common workspace root |
13
+ | Knowledge | `oats.okf` 1.4.1 |
14
+ | Messaging | `oats.aweb` 1.8.0, bound to our existing team |
15
+ | Authoring | `oats.authoring` 1.0.0 |
16
+ | Worker scope | The child OATS Git repository, selected explicitly |
17
+ | Harvester runtime/model | Pi, `openai-codex/gpt-5.5`, configured for this machine |
18
+
19
+ Package acquisition used the published kernel's catalog and exact locks.
20
+ The executable OKF and aweb capabilities were explicitly trusted.
21
+ `oats doctor` passed. A separate published-authoring probe confirmed that
22
+ `integration-authoring`, `skill-craft`, and `soul-craft` materialized for an
23
+ authoring soul.
24
+
25
+ ## Two useful tasks
26
+
27
+ The **Pi documentation worker**, `docs-expert-readme-claims`, corrected a
28
+ claim that all captured conversations were signed. Native transcript turns
29
+ have content hashes; signed aweb messages preserve their original
30
+ signatures. Its code-review handoff led to the
31
+ [documentation correction](https://github.com/awebai/oats/commit/ef4a1a6599da88e213b2a6a8f3918099aa5ba984).
32
+
33
+ The **Claude Code worker**, `cli-dev-lock-fix`, fixed a stream-lock race.
34
+ A late contender could classify a live holder's lock as stale and enter the
35
+ same critical section. The fix uses holder liveness and an ownership token;
36
+ review also caught an acquisition loop that could retry filesystem errors
37
+ forever. See the [initial fix](https://github.com/awebai/oats/commit/1036381)
38
+ and [review correction](https://github.com/awebai/oats/commit/81735f6e936d1b6aa0a3ad62d12953d494851cc8).
39
+
40
+ Both workers used isolated worktrees, committed changes, and reported
41
+ through aw. Review happened before integration. Claude needed its initial
42
+ folder-trust and development-channels confirmations; Pi started directly.
43
+
44
+ ## What carried forward
45
+
46
+ Each worker invoked OKF harvest. Its temporary harvester promoted a lesson
47
+ into the source soul and committed it on the worker's branch:
48
+
49
+ - [Content-addressed turn IDs do not authenticate native capture](https://github.com/awebai/oats/commit/91993a0b85db132c59c32d43ee2c90ec5569bd50).
50
+ - [Lock ownership and the limits of comparing timeout thresholds](https://github.com/awebai/oats/commit/120e3474b93efc0d37f94c426327f802e27893ea).
51
+
52
+ After the documentation promotion landed, the predecessor retired locally:
53
+ its worktree, branch, and home were removed. Its aweb alias remained on the
54
+ server despite the hook reporting success. A new Pi instance of the same
55
+ soul with a different name, `docs-expert-capture-contract-check`, started a real
56
+ follow-up task checking the capture contract documentation.
57
+
58
+ Its first report named the promoted file:
59
+ `soul/knowledge/lessons/content-addressed-turn-ids-not-authentication.md`.
60
+ The worker said the lesson reinforced the distinction between unsigned
61
+ native turns and preserved source signatures, and explicitly said it did
62
+ not change what it was already about to do.
63
+
64
+ That verifies useful work, reviewed promotion, local retirement, and a
65
+ successor reading the updated soul. Remote identity retirement remains
66
+ incomplete. The example does not establish a measured productivity
67
+ improvement.
68
+
69
+ ## What the run exposed
70
+
71
+ The run found first-use problems that unit tests alone had not resolved:
72
+
73
+ - A fresh scope needed `mkdir -p agents` before `oats create`; the fix is in
74
+ the 0.22.1 changes.
75
+ - The default harvester model assumed a provider absent on this machine.
76
+ The workspace now selects an authenticated model explicitly.
77
+ - All four initial worker and harvester retirements reported successful
78
+ identity deletion but left their aweb aliases on the server. Local
79
+ cleanup completed; remote cleanup requires a team administrator, and
80
+ names cannot be reused until it succeeds. Temporary harvesters are now
81
+ excluded from messaging to avoid adding aliases while this is fixed.
82
+ - A combined workspace roster did not make the workspace a spawn scope for
83
+ every child repository. Commands select the owning repository explicitly.
84
+
85
+ The [first-team guide](first-team.md) includes these setup details. The
86
+ package owners are responsible for improving their defaults; the kernel
87
+ continues to resolve capabilities through the same replaceable contracts.
@@ -0,0 +1,179 @@
1
+ # Run your first OATS team
2
+
3
+ Start with one repository and one small, real task. An OATS soul keeps the
4
+ role and knowledge; an instance gets a working session and a Git worktree.
5
+ Review its work, let it promote useful notes, then retire the instance.
6
+
7
+ This guide follows the published **0.22.0** path exercised on 2026-09-05
8
+ with `oats.dev` 1.0.0, `oats.okf` 1.4.1, `oats.aweb` 1.8.0, and
9
+ `oats.authoring` 1.0.0. The [qualification example](first-team-demo.md)
10
+ records the actual tasks and outcomes. Existing OAS users should follow
11
+ [the migration guide](migration-from-oas.md) first.
12
+
13
+ ## Install and choose a scope
14
+
15
+ Have Node.js 22+, Git, tmux, and an authenticated agent runtime available.
16
+ Launch Pi or Claude Code once yourself to confirm that your chosen model
17
+ works. The current OKF package runs its harvester in **Pi**, including when
18
+ its working agent uses Claude Code, so this configuration needs Pi too.
19
+
20
+ ```bash
21
+ npm install -g @awebai/oats@latest
22
+ pi install npm:@awebai/oats-pi@latest
23
+ node --version
24
+ tmux -V
25
+ oats version
26
+ ```
27
+
28
+ Install matching kernel and adapter versions from the same release.
29
+
30
+ Use a repository with an initial Git commit. Keep your normal working
31
+ changes committed or otherwise accounted for before giving an agent work.
32
+ The commands below run from that repository:
33
+
34
+ ```bash
35
+ cd /path/to/project
36
+ oats init --package oats.dev --config default
37
+ oats list
38
+ ```
39
+
40
+ Initialization acquires the package closure and writes an editable
41
+ `oats-config.yaml` plus an exact lock. It does not create a team account or
42
+ approve executable hooks. `oats.dev` is our reference development policy;
43
+ edit its team name and provider choices for your own project.
44
+
45
+ For several repositories, initialize their common workspace directory
46
+ instead. Run create/spawn/retire with `--dir /path/to/workspace/project` for
47
+ the repository that owns the soul. `oats status --team` at the workspace
48
+ shows the combined roster, but that does not select a repository for spawn.
49
+
50
+ ## Set the model and connect messaging
51
+
52
+ Edit the existing entries in `oats-config.yaml`; do not append a second
53
+ `capabilities` block. Set `team.name` to your own team. If you already use
54
+ aw, set `team.id` to its exact existing ID so instances join that team.
55
+
56
+ Under `capabilities.layers`, configure the model your Pi installation can
57
+ actually use. This example was used in our qualification; replace the
58
+ model if you authenticate through another provider:
59
+
60
+ ```yaml
61
+ knowledge:
62
+ capability: oats.okf
63
+ from: installed
64
+ settings:
65
+ harvest-model: openai-codex/gpt-5.5
66
+ messaging:
67
+ capability: oats.aweb
68
+ from: installed
69
+ global: true
70
+ souls:
71
+ memory-harvest: false
72
+ tasks: none
73
+ ```
74
+
75
+ The `oats.okf` 1.4.1 default harvester model is
76
+ `github-copilot/gpt-5.5`; it will not work without that provider. The
77
+ messaging exclusion above keeps temporary harvesters from creating aliases
78
+ while an identity-retirement issue is being corrected. Workers still get
79
+ messaging identities. With a `souls` exclusion, state `global: true`
80
+ explicitly so scope-level commands such as `oats aweb setup` stay active.
81
+
82
+ Review and approve the executable capabilities, then check onboarding:
83
+
84
+ ```bash
85
+ oats trust oats.okf
86
+ oats trust oats.aweb
87
+ oats aweb setup
88
+ oats doctor
89
+ ```
90
+
91
+ `oats aweb setup` prints the next step: install the `aw` CLI if needed,
92
+ initialize an identity with `aw init`, then create or join your team. Follow
93
+ that output and rerun setup until it confirms membership. For an existing
94
+ team, join it rather than creating another with the same name. Setup's exit
95
+ status alone does not establish that onboarding finished.
96
+
97
+ Messaging is optional. To work without it, set `messaging: none`, omit the
98
+ aweb trust/setup commands, and keep the knowledge configuration above.
99
+ Packages, souls, Git worktrees, and local knowledge do not require hosted
100
+ messaging. See [configuration](configuration.md) for other providers.
101
+
102
+ ## Give an instance a real task
103
+
104
+ On 0.22.0, create the roster directory first; a fresh-scope creation fix is
105
+ included in 0.22.1.
106
+
107
+ ```bash
108
+ mkdir -p agents
109
+ oats create backend-expert --type developers --repo . --work worktree --runtime pi
110
+ ```
111
+
112
+ Edit `agents/backend-expert/soul/AGENTS.md` to describe the role, repository
113
+ conventions, and the checks that matter. Review and commit the new soul,
114
+ configuration, lock, generated ignore rules, and adopted template base under
115
+ `.agents/config-templates/adopted/`. A worktree starts from a Git commit;
116
+ uncommitted soul changes are not present on the worker's branch. Keep aw
117
+ credentials out of Git.
118
+
119
+ Then launch one bounded task:
120
+
121
+ ```bash
122
+ oats spawn backend-expert --purpose first-fix --task "Fix one small issue, run the relevant checks, commit the change, and report what changed. Capture any reusable lesson and harvest it before finishing."
123
+ oats status --team
124
+ ```
125
+
126
+ Choose `--runtime claude` at creation for a Claude Code worker. Today its
127
+ first session can require **two interactive confirmations**: folder trust
128
+ and the development-channels confirmation used by the aweb integration.
129
+ Attach to the tmux session printed by spawn and answer them. A created
130
+ window is not evidence that the agent has started working.
131
+
132
+ Each instance has a home under `agents/<soul>/instances/<instance>/`; its
133
+ `work/` directory is the repository worktree. Read the instance's report
134
+ and review its commits there. Agents using aw run coordination commands
135
+ from their own home, which holds their identity.
136
+
137
+ ## Harvest, review, and retire
138
+
139
+ With OKF active, the worker keeps state and notes in its home. After a
140
+ commit it can run `oats okf harvest` there. If it reports pending notes but
141
+ has not harvested, ask it to do so, or run the command from that instance's
142
+ home yourself. Retirement does not initiate knowledge promotion.
143
+
144
+ The harvester reviews notes, updates the soul's knowledge, and commits the
145
+ promotion into the worker's branch. Let it finish before final review or
146
+ retirement. Review **all** commits, including the promotion, and merge the
147
+ accepted work into the repository's main branch through your normal
148
+ workflow. Then, from the repository scope:
149
+
150
+ ```bash
151
+ oats retire backend-expert-first-fix
152
+ oats status --team
153
+ ```
154
+
155
+ Read the retirement result, including any retained home or recovery path.
156
+ With aweb enabled, also inspect `oats aweb roster`: local retirement alone
157
+ is not proof that a remote alias was removed. During the current hosted
158
+ alias-retirement issue, use a fresh purpose for the next instance and have
159
+ the team administrator clear any stale alias before reusing its name.
160
+
161
+ Start the same soul on the next useful task after its knowledge commit is
162
+ on main. Check that the new instance can find and use the promoted lesson.
163
+ That completes the first lifecycle: useful work, reviewed learning, clean
164
+ local retirement, and a successor with the updated soul.
165
+
166
+ ## Optional conversation record
167
+
168
+ Knowledge promotion and conversation capture are separate. To enable the
169
+ local transcript record and query it:
170
+
171
+ ```bash
172
+ oats setup
173
+ oats capture --status
174
+ oats recall "a phrase from your completed task"
175
+ ```
176
+
177
+ Capture reads supported transcripts and aweb logs after setup, subject to
178
+ ignore rules. Native turns are content-addressed; signed aweb messages
179
+ retain their source signatures. See [the turn record](../README.md#the-turn-record).
@@ -158,7 +158,20 @@ instance homed inside a repository with its own `.claude/skills` sees those
158
158
  too. Project *settings* — hooks, plugins, permissions, custom agents — resolve
159
159
  from the instance home rather than from ancestors.
160
160
 
161
- Both runtimes record what they actually expose in `instance.json` under
161
+ Codex is available with `--runtime codex`. It starts in the instance home,
162
+ reads `AGENTS.md` and `.agents/skills` natively, and receives `TASK.md` as its
163
+ initial prompt. User configuration, approval policy, ancestor instructions and
164
+ ambient skill sources remain native. Worktrees are already below the instance
165
+ home; checkout/attached paths outside it use Codex's normal approval handling
166
+ and may require approval for writes, depending on the operator's policy.
167
+ OATS does not pass `--add-dir`, which Codex refuses under some native policies.
168
+ OpenAI-prefixed model preferences are translated to
169
+ Codex ids; other provider preferences fall back to its configured default.
170
+ The Desktop model field accepts a native id without using Pi's model catalog.
171
+ This launch support does not supply an aweb channel for Codex: agents can use
172
+ `aw` from their home, with automatic wake delivery tracked separately.
173
+
174
+ All runtimes record what they actually expose in `instance.json` under
162
175
  `composition.materialized.runtimePosture`: the OATS-composed set, what is
163
176
  curtailed, and what remains ambient. The deviation from strict composition is
164
177
  auditable rather than implied.
@@ -1,39 +1,42 @@
1
- # Integrations
1
+ # Integrations: binding an implementation to a contract
2
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.
3
+ An **integration** is a capability package selected to fill one exclusive
4
+ slot: `knowledge`, `messaging` (the communication contract), or `tasks`.
5
+ The contracts themselves are in [the OATS contracts](layers.md); this
6
+ document is about choosing an implementation, and about building one.
7
7
 
8
- Read [Capability packages](capabilities.md) first for manifests, acquisition,
8
+ Read [capability packages](capabilities.md) first for manifests, acquisition,
9
9
  targeting, instance-local composition, locks, trust, hooks, and commands.
10
10
 
11
- ## Fundamental-layer contract
11
+ ## The slots
12
12
 
13
- For each soul, OATS resolves zero or one implementation for each pluggable
14
- layer:
13
+ For each soul, OATS resolves zero or one implementation per slot:
15
14
 
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` |
15
+ | Slot | Contract | Bundled implementations |
16
+ | --- | --- | --- |
17
+ | `knowledge` | [knowledge](layers.md#the-knowledge-contract) | `oats.okf` |
18
+ | `messaging` | [communication](layers.md#the-communication-contract) | `oats.aweb` |
19
+ | `tasks` | [tasks](layers.md#the-tasks-contract) | `oats.jira`, `oats.linear` |
21
20
 
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.
21
+ A capability manifest becomes an integration by declaring one `layer`. It
22
+ may not declare several. Two active packages for one slot and one soul are a
23
+ configuration error; capabilities without `layer` compose additively.
25
24
 
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.
25
+ Exclusivity is the point. Task state belongs to the selected tasks
26
+ implementation even when a messaging tool also offers task features, and
27
+ conversation belongs to the messaging implementation even when a tracker
28
+ offers comments.
28
29
 
29
30
  ## Selecting an integration
30
31
 
31
- New config activates the package for the intended target:
32
+ Configuration activates the package for the intended target; the manifest
33
+ already declares the slot, so `oats use` writes the entry under
34
+ `capabilities.layers.<slot>`:
32
35
 
33
36
  ```yaml
34
37
  agent-types:
35
38
  product-agents:
36
- description: Planner/developer/reviewer souls (they declare `type: product-agents`)
39
+ description: Planner, developer, and reviewer souls (they declare `type: product-agents`)
37
40
 
38
41
  capabilities:
39
42
  layers:
@@ -59,65 +62,80 @@ capabilities:
59
62
  project: Agent Platform
60
63
  ```
61
64
 
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
65
  CLI equivalents:
67
66
 
68
67
  ```bash
69
68
  oats use oats.okf --global
70
69
  oats use oats.aweb --type product-agents
71
70
  oats use oats.linear --type product-agents
71
+ oats use none --layer tasks # leave an inherited slot deliberately unfilled
72
72
  ```
73
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`).
74
+ Every matching soul gets one implementation per slot. A non-matching soul can
75
+ resolve a different one or leave a slot unfilled. `none` is a layer
76
+ selection, not a policy: a soul with `messaging: none` has no address, which
77
+ is different from a soul whose type restricts its reach.
78
78
 
79
79
  ## Bundled integrations
80
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.
81
+ **`oats.okf`** fills `knowledge`: OKF soul bundles, instance `STATE.md`,
82
+ `log.md`, and `notes/`, the `okf` and `memory-harvest` skills, and
83
+ `oats okf harvest`, which promotes pending notes after a commit through the
84
+ capability-defined `memory-harvest` soul. Its scaffold and spawn hooks own
85
+ memory mechanics; the kernel stays knowledge-format agnostic.
94
86
 
95
- ### `oats.jira`
87
+ **`oats.aweb`** fills `messaging`: mints an instance identity at spawn,
88
+ removes it at retire, contributes the aweb messaging and team skills, wires
89
+ the channel plugin so sessions are woken by mail, and exposes
90
+ `oats aweb roster` and `oats aweb setup`. Requires the `aw` CLI.
96
91
 
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`.
92
+ **`oats.jira`** fills `tasks`: the `jira-tasks` protocol and an advisory
93
+ spawn hook. Requires `acli`; settings commonly include `site` and `project`.
100
94
 
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
95
+ **`oats.linear`** fills `tasks`: JSON-first `oats linear` commands, the
96
+ `linear-tasks` skill, and an advisory spawn hook. Uses `LINEAR_API_KEY`;
97
+ secrets never belong in OATS config. See
106
98
  `capabilities/oats-linear/README.md` for its support boundary.
107
99
 
108
100
  > **Removed: `oats.web`.** The browser web-panel capability was retired in
109
101
  > 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`.
102
+ > zero-dependency loopback server. If an `oats-lock.json` or
103
+ > `oats-config.yaml` still names `oats.web`, remove that entry. Full
104
+ > migration steps: [desktop-succession](desktop-succession.md).
105
+
106
+ ## Building an integration
107
+
108
+ Building an integration is implementing a contract. The checklist per slot:
109
+
110
+ **Any slot.** A namespaced capability manifest with exactly one `layer`; an
111
+ `inject` block that tells the instance what this implementation is and which
112
+ skill to load before first use; skills that carry the craft; commands that
113
+ support `--json`; hooks only on the accepted events; `requires` for every
114
+ host command and runtime package; `environment` for every launch variable
115
+ contributed, under the vendor prefix. Package commands and hooks reach the
116
+ kernel only through `OATS_CLI_BIN` and the JSON envelope, never by importing
117
+ kernel files. Never name target souls in the manifest; targeting belongs to
118
+ configuration.
119
+
120
+ **Knowledge.** Scaffold the soul's store on `soul-scaffold`; create instance
121
+ ephemeral state on `spawn`; teach the read side (index-first, selective,
122
+ binding) in the inject and skill; ship a harvester as a capability-defined
123
+ soul and a command that spawns it attached to the source instance's tree;
124
+ route promotions by custody (commit, pull request, or direct edit); apply the
125
+ promotion doctrine in the contract; and, once the `harvest` event exists,
126
+ declare it instead of relying on the instance to call the command.
127
+
128
+ **Communication.** Mint an address on `spawn` with a `required` hook and
129
+ remove it on `retire`; supply the roster; teach send, reply, chat, and "read
130
+ the event first" in the inject and skill; contribute launch arguments so the
131
+ session is woken; enforce the soul type's `reach` on both sides; state
132
+ whether the address outlives the instance; and keep task coordination out.
133
+
134
+ **Tasks.** Teach claim, update, block, hand off, and complete; identify the
135
+ instance to the tracker in a way that survives it; keep conversation out.
136
+
137
+ The framework's `integrations-expert` soul remains the specialist for
138
+ contract design, and the `integration-authoring` skill routes work to it.
139
+ Test an integration as a capability package: acquire, lock, trust, activate,
140
+ spawn, retire, with the golden fixtures as the behavior oracle for the kernel
141
+ side.