@awebai/oats 0.26.0 → 0.27.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.
@@ -28,7 +28,7 @@ refusals below remain authoritative.
28
28
 
29
29
  Optional features are negotiated from the probe's `features` array. Starting
30
30
  an existing home requires `session-start`; named launch configurations and
31
- runtime/permission overrides require `launch-config`; restarting a running
31
+ harness/permission overrides require `launch-config`; restarting a running
32
32
  home also requires `session-restart`. Desktop checks the corresponding
33
33
  `remote` entries before offering these operations for a server. The router
34
34
  then probes the execution host before sending a mutation. An absent feature
@@ -48,6 +48,63 @@ no progress prose (progress goes to stderr):
48
48
  - success (exit 0): `{"schemaVersion":1,"ok":true,"result":{...}}`
49
49
  - failure (nonzero exit): `{"schemaVersion":1,"ok":false,"error":{"code":"...","message":"..."}}`
50
50
 
51
+ Either may also carry `"warnings":[…]` (0.27.0+), present only when there is
52
+ something to say. The one warning so far is `deprecated-runtime-name` (see
53
+ [the harness rename](#the-harness-rename-feature-harness-oats-0270)). `oats status
54
+ --json`, whose document is not an envelope, carries the same `warnings` beside
55
+ its `problems`. In text mode the warning is one `oats: warning: …` line on stderr.
56
+
57
+ ## The harness rename (feature `harness`, OATS 0.27.0)
58
+
59
+ What starts an instance (pi, claude or codex) is its **harness**. 0.27.0 renames
60
+ the kernel's `runtime` to `harness` everywhere it means that:
61
+
62
+ - Outputs speak only the new names.
63
+ - Every input written before 0.27.0 still works. The rule is read either,
64
+ write new: the old spelling is read as the new one, and the next write
65
+ records the new one.
66
+ - A command that read an old spelling answers **one** warning:
67
+ `{"code":"deprecated-runtime-name","key":"runtime","replacement":"harness","sources":[…],"message":"…"}`.
68
+ `sources` names each place it read the old spelling (a flag, a file and its
69
+ key, a home).
70
+ - A pair that disagrees is refused rather than guessed, for example
71
+ `--harness pi --runtime claude`, or both keys with different values.
72
+ - A later release drops the old spellings.
73
+
74
+ Gate on the feature `harness`. A kernel without it speaks the old names: the
75
+ routed commands (`--server`) already translate for such a host, sending
76
+ `--runtime` and `runtime` keys to it and reading its `runtimes` list.
77
+
78
+ | Surface | Before 0.27.0 | 0.27.0 | Old spelling still accepted? |
79
+ |---|---|---|---|
80
+ | `oats version --json` | `runtimes: [pi, claude, codex]` | `harnesses: [...]`, feature `harness` | **Dropped**: no `runtimes` alias; gate on the feature |
81
+ | Flag on `spawn` (and `--preview`), `session start`/`restart`, `launch-config preview`, and their `--server` forms | `--runtime <h>` | `--harness <h>` | Yes, with the warning (the okf 2.1.5 harvest worker passes `--runtime` to spawn). Both flags disagreeing → `E_BAD_ARGS` |
82
+ | `oats status --json`: `agents[]` rows (soul default) and `agents[].instances[]` rows | `runtime` | `harness` | Output only |
83
+ | `oats status --json`: instance rows' `composition.materialized` | `runtimePackages`, `runtimePosture` | `harnessPackages`, `harnessPosture` | Output only |
84
+ | `oats inspect --json` `souls[]` rows, remote roster rows | `runtime` | `harness` | Output only; a pre-0.27 host's `runtime` rows are read as `harness` |
85
+ | `oats inspect --home --json` `instance` | `runtime` | `harness` | Output only |
86
+ | The launch plan's package check (`launch-config preview` `problems[]`) | `runtime-packages` | `harness-packages` | Output only |
87
+ | Soul `soul.yaml` (member souls and capability-defined agents) | `runtime:` | `harness:` | Yes, **without** a warning: released capabilities (oats.aweb 1.13.1) ship `runtime:`, and the operator cannot fix a provider's file. Both, disagreeing → `E_BAD_MANIFEST` |
88
+ | `oats-local.yaml` `launch-configs.<name>` | `runtime:` | `harness:` | Yes, with the warning. Both, disagreeing → `E_WORKSPACE_SCHEMA`. `launch-config set` writes `harness` (a `runtime` in its `--file` definition too) |
89
+ | `launch-config list/preview --json` rows and `selection` | `runtime` | `harness` | Output only |
90
+ | Home `instance.json` | `runtime`; launch recipe `launch` version 1 `{runtime}` | `harness`; recipe version **2** `{harness}` | Yes, with the warning naming the home: a 0.26.0 home inspects, starts, restarts and retires; its next start or restart records the new names |
91
+ | `oats spawn … --preview` decision | `effective.runtime` | `effective.harness` | Output only. The revision digests the key names, so a decision previewed by a 0.26 kernel is `E_DECISION_STALE` at apply (with the fresh decision) |
92
+ | `spawn`/`session` results, `spawned` event `data` | `runtime` | `harness` | Output only |
93
+ | Schedule definitions (`schedule add/update --spec-json`, stored jobs, `schedule list`) | `runtime` | `harness` | Yes, with the warning. A stored job is read in the new name and saved in it next time. Both, disagreeing → `E_SCHEDULE_INVALID` (a stored job: invalid on its own) |
94
+ | Schedule run records (`lastRun`, `recentRuns`) | `startedRuntime` | `startedHarness` | Output; a 0.26.0 record's `startedRuntime` is still read |
95
+ | Error codes | `E_UNSUPPORTED_RUNTIME`, `E_RUNTIME_PACKAGE`, `E_RUNTIME_RESOURCE_MISSING` | `E_UNSUPPORTED_HARNESS`, `E_HARNESS_PACKAGE`, `E_HARNESS_RESOURCE_MISSING` | Output only |
96
+ | Hook environment (spawn and launch hooks) | `OATS_RUNTIME`, `OATS_PREVIOUS_RUNTIME` | `OATS_HARNESS`, `OATS_PREVIOUS_HARNESS` | Both are set, with the same values, for released hooks |
97
+ | Capability manifest `requires[]` harness package | `runtime` | `harness` | Yes, **without** a warning (a provider's file); a row naming both is refused |
98
+ | Package verification `loadedBy` | `runtime-discovery` | `harness-discovery` | Output only |
99
+
100
+ Unchanged, because they do not name the harness: the session endpoint
101
+ vocabulary (`runtimeAuthority`, `runtimeState`/`runtimeError` in liveness,
102
+ `E_RUNTIME_ENDPOINT_UNKNOWN`, `E_RUNTIME_AUTHORITY_MISMATCH`,
103
+ `E_RUNTIME_QUIESCE_FAILED`); `capabilityRuntime`; the retirement baseline's
104
+ `runtime`; oats.okf's `harvest-runtime` setting; and the kernel's
105
+ "runtime-neutral" design. Hook stdin carries no `launch.runtime` (no 0.26 hook
106
+ emitter wrote it).
107
+
51
108
  ## Inspect, readiness and operation run on the workspace model (`operationsApi: 2`, `soulsApi: 2`, `readinessApi: 2`, OATS 0.26.0)
52
109
 
53
110
  On a workspace deployment (an `oats-local.yaml` in reach of `--dir`), and for
@@ -121,7 +178,7 @@ payload the spawn recorded for a home, or the resolution computes for a soul.
121
178
  "subject":{"kind":"instance","instance":"release-manager-x","home":"/w/agents/release-manager/instances/release-manager-x","soul":"release-manager"},
122
179
  "workspace":{"key":"github.com/northwind/agents","name":null,"deployment":"/w","commit":"461b9c24…","standalone":false},
123
180
  "souls":[{"soulsApi":2,"name":"release-manager","repoKey":"github.com/northwind/agents","commit":"461b9c24…","team":"engineering",
124
- "kind":null,"path":null,"description":"Cuts, verifies and announces platform releases.","work":"worktree","runtime":null,"model":null,
181
+ "kind":null,"path":null,"description":"Cuts, verifies and announces platform releases.","work":"worktree","harness":null,"model":null,
125
182
  "declarations":{"requires":null,"defaults":null,"knowledge":{"owns":"release-manager","reads":["platform-engineer"]},"teams":null,"resources":null,"children":null,
126
183
  "capabilities":{"nw-release-tooling":{"from":"here"},"nw-deploy":{"from":"package"}}},
127
184
  "declarationProblems":[],
@@ -138,7 +195,7 @@ payload the spawn recorded for a home, or the resolution computes for a soul.
138
195
  "operations":[{"name":"inspect","kind":"view","command":"inspect","context":"home","description":"…","args":[],"argv":["okf","inspect"],"available":true,"reason":null}]}],
139
196
  "knowledge":{"provider":"oats.okf","version":"2.1.3","operations":[{"name":"inspect","kind":"view","available":true,"reason":null}]},
140
197
  "instance":{"home":"/w/agents/release-manager/instances/release-manager-x","instance":"release-manager-x","agent":"release-manager",
141
- "runtime":"pi","model":null,"yolo":null,"launched":false,"createdAt":"<iso>","resolution":"7217670b…",
198
+ "harness":"pi","model":null,"yolo":null,"launched":false,"createdAt":"<iso>","resolution":"7217670b…",
142
199
  "soulDir":"/w/agents/release-manager/souls/461b9c24929c",
143
200
  "instructions":{"file":"/w/agents/release-manager/instances/release-manager-x/AGENTS.md","text":"…","truncated":false,
144
201
  "sources":[{"source":"kernel:instance-boundary","file":"…"},{"source":"capability:oats.okf","file":"…/.oats/modules/oats.okf/injects/okf.md"}]}},
@@ -471,7 +528,7 @@ home's removal, so a retired instance's `retired` event is still readable).
471
528
 
472
529
  ```json
473
530
  {"eventsApi":1,"instance":"dev-1","home":"/abs/home","count":7,"returned":7,"truncated":false,
474
- "events":[{"eventsApi":1,"at":"<iso>","instance":"dev-1","home":"/abs/home","producer":"kernel","kind":"spawned","data":{"agent":"dev","work":"worktree","branch":"agents/dev-1","runtime":"claude","model":null,"parentInstance":null,"relation":null,"launched":true}},
531
+ "events":[{"eventsApi":1,"at":"<iso>","instance":"dev-1","home":"/abs/home","producer":"kernel","kind":"spawned","data":{"agent":"dev","work":"worktree","branch":"agents/dev-1","harness":"claude","model":null,"parentInstance":null,"relation":null,"launched":true}},
475
532
  {"…":"launched | restarted | stopped | stop-refused | retire-planned | worktree-retained | worktree-removed | branch-deleted | retired | child-spawn-refused"}],
476
533
  "lastEvent":{"kind":"stopped","at":"<iso>","producer":"kernel"},
477
534
  "waitingOnYou":null,
@@ -628,12 +685,12 @@ unchecked, echoed a stored `definition.id` without checking it, and named a
628
685
  The Spawn modal's fields are backed by the kernel's own decision, taken **before
629
686
  any side effect**: `oats spawn <agent> [same flags as a real spawn] --preview --json`
630
687
  runs every preflight a spawn runs (placement, composition, resources,
631
- executable, runtime packages, child-spawn policy) and returns what the spawn
688
+ executable, harness packages, child-spawn policy) and returns what the spawn
632
689
  *would* do — then returns without creating a home, branch or worktree.
633
690
 
634
691
  ```json
635
692
  {"spawnPreviewApi":1,"preview":true,"agent":"dev","kind":"persistent","instance":"dev-fix-login","home":"/abs/agents/dev/instances/dev-fix-login",
636
- "repo":"/abs/repo","work":"worktree","runtime":"claude","model":"opus","modelSource":"explicit","launchConfig":null,"yolo":false,"backend":"tmux",
693
+ "repo":"/abs/repo","work":"worktree","harness":"claude","model":"opus","modelSource":"explicit","launchConfig":null,"yolo":false,"backend":"tmux",
637
694
  "branch":"agents/dev-fix-login","base":{"ref":"HEAD","oid":"<oid>"},"worktree":"/abs/agents/dev/instances/dev-fix-login/work",
638
695
  "relation":null,"parentInstance":null,"policy":{"childSpawns":{"allowed":true,"origin":{"kind":"default","detail":"…"}}},
639
696
  "executable":"/abs/bin/claude","capabilities":["oats.core"],"skills":["oats-operate","oats-souls"],"task":"…"}
@@ -650,7 +707,7 @@ executable, runtime packages, child-spawn policy) and returns what the spawn
650
707
  the worktree **from that exact oid**.
651
708
  - **Model**: `model`/`modelSource` are the resolved selection. Omitting
652
709
  `--model` **inherits** the launch configuration's or soul's preference;
653
- `--model @native-default` is the explicit "use the runtime's own default"
710
+ `--model @native-default` is the explicit "use the harness's own default"
654
711
  (`modelSource: "native default (explicit)"`). These are different requests
655
712
  and the UI must not relabel one as the other.
656
713
  - **Policy**: `policy.childSpawns` is what this instance will record (soul
@@ -722,11 +779,11 @@ the pre-fix marker and is never accepted for dispatch.
722
779
  - **Bounded preflight**: every native probe a preview runs (`pi --list-models`,
723
780
  `pi list`, `claude plugin list`) shares ONE budget (20 s default), runs in its
724
781
  own process group and is group-killed on timeout; `preflight {status:
725
- complete|timeout, budgetMs, elapsedMs}` says which. A hanging runtime cannot
782
+ complete|timeout, budgetMs, elapsedMs}` says which. A hanging harness CLI cannot
726
783
  hang a preview.
727
784
  - **Confirmed apply contract** (0.24.10+, feature `spawn-apply-2`,
728
785
  `spawnApplyApi: 1`) — what a GUI may promise at "Confirm spawn":
729
- - `decision` gains **`effective {repo, work, runtime, model, launchConfig,
786
+ - `decision` gains **`effective {repo, work, harness, model, launchConfig,
730
787
  yolo, backend, childSpawns, relation{kind, anchor{instance, agentsRoot}}}`**
731
788
  and `revision` hashes placement + effective. An inherited default that would
732
789
  change what launches (the soul's model edited between preview and apply,
@@ -1342,7 +1399,7 @@ are described in [the operations contract](design/operations-contract.md).
1342
1399
 
1343
1400
  ```text
1344
1401
  oats session start --home /absolute/home [--server id] \
1345
- [--launch-config name] [--runtime pi|claude|codex] \
1402
+ [--launch-config name] [--harness pi|claude|codex] \
1346
1403
  [--model id] [--yolo|--no-yolo] --json
1347
1404
  oats session restart --home /absolute/home [the same options] --json
1348
1405
  ```
@@ -1366,7 +1423,7 @@ oats launch-config list [--dir /scope | --home /home | --soul name --agents-root
1366
1423
  oats launch-config set name --file /private/definition.json [--keep-env] --dir /scope --json
1367
1424
  oats launch-config remove name --dir /scope --json
1368
1425
  oats launch-config preview (--home /home | --soul name --agents-root /scope/agents --dir /scope) \
1369
- [--launch-config name] [--runtime runtime] [--model id] [--yolo|--no-yolo] --json
1426
+ [--launch-config name] [--harness harness] [--model id] [--yolo|--no-yolo] --json
1370
1427
  ```
1371
1428
 
1372
1429
  All accept `--server id`. Scope edits follow the registration; inspection and
@@ -1375,7 +1432,7 @@ is serialized to SSH stdin and read on the host with `--file -`; the local
1375
1432
  filename is never passed to the server as though it existed there.
1376
1433
 
1377
1434
  The list result supplies `context`, `selected` and `configurations`. Each
1378
- configuration has a name, runtime, executable, literal argument array,
1435
+ configuration has a name, harness, executable, literal argument array,
1379
1436
  environment, model, permission choice and declaring `source`. Environment
1380
1437
  literals appear as `{ "redacted": true }`; references appear as
1381
1438
  `{ "fromEnv": "VARIABLE_NAME" }`. Optional executable/model/yolo fields can be
@@ -1410,7 +1467,7 @@ See [launch configuration syntax](configuration.md) and
1410
1467
  | `warnings` | string[] | non-fatal warnings (always an array) |
1411
1468
  | `tmux` | {session,window} \| null | tmux target |
1412
1469
 
1413
- Additional informative fields: `repo`, `runtime`, `model`, `parent`,
1470
+ Additional informative fields: `repo`, `harness`, `model`, `parent`,
1414
1471
  `sibling` (explicit sibling cluster link when a root-level sibling relation
1415
1472
  was declared, else null), `relation` (`child`/`sibling`/`parent` when a
1416
1473
  relation was declared at spawn, else null), `spawnOrigin`, `attach`.
@@ -9,7 +9,7 @@ The Desktop roster is the place to return to it:
9
9
  - The hierarchy's action popover offers **Start…** for a stopped instance.
10
10
  - An unknown status is shown as unknown, not as permission to launch another process.
11
11
 
12
- The Start/Restart dialog names the existing instance, runtime and host. Choose
12
+ The Start/Restart dialog names the existing instance, harness and host. Choose
13
13
  a named launch configuration or keep the recorded launch. Without a selected
14
14
  configuration, the harness can also be changed directly. A named configuration
15
15
  fixes its harness; model and permission choices can override its defaults.
@@ -53,7 +53,7 @@ Use the server's workspace to manage configurations defined on that server.
53
53
  Desktop sends `POST /api/start/<instance>?ws=…&home=…` (and `server=…` for a
54
54
  remote instance). The backend resolves that exact roster identity and calls
55
55
  `oats session start --home <absolute-home> [--server <id>] [--model <model>] --json`.
56
- Launch choices add `--launch-config`, `--runtime` or `--yolo`/`--no-yolo`.
56
+ Launch choices add `--launch-config`, `--harness` or `--yolo`/`--no-yolo`.
57
57
  Restart uses `POST /api/restart/<instance>?ws=…&home=…` and the single kernel
58
58
  command `oats session restart` with the same selectors and choices.
59
59
  Configuration inspection and editing use `POST /api/launch-configs?ws=…`,
@@ -103,7 +103,7 @@ oats spawn backend-expert --purpose first-fix --task "Fix one small issue, run t
103
103
  oats status
104
104
  ```
105
105
 
106
- `--runtime pi|claude|codex` picks the harness; complete any native folder
106
+ `--harness pi|claude|codex` picks the harness; complete any native folder
107
107
  trust or authentication prompt in the printed session. The instance home is
108
108
  `agents/<soul>/instances/<instance>/`; `work/` is its repository view;
109
109
  `.oats/modules/<cap>/` and `.agents/skills/<cap>/` are the copied capabilities;
@@ -162,7 +162,7 @@ instance homed inside a repository with its own `.claude/skills` sees those
162
162
  too. Project *settings* — hooks, plugins, permissions, custom agents — resolve
163
163
  from the instance home rather than from ancestors.
164
164
 
165
- Codex is available with `--runtime codex`. It starts in the instance home,
165
+ Codex is available with `--harness codex`. It starts in the instance home,
166
166
  reads `AGENTS.md` and `.agents/skills` natively, and receives `TASK.md` as its
167
167
  initial prompt. User configuration, approval policy, ancestor instructions and
168
168
  ambient skill sources remain native. Worktrees are already below the instance
@@ -175,8 +175,8 @@ The Desktop model field accepts a native id without using Pi's model catalog.
175
175
  This launch support does not supply an aweb channel for Codex: agents can use
176
176
  `aw` from their home, with automatic wake delivery tracked separately.
177
177
 
178
- All runtimes record what they actually expose in `instance.json` under
179
- `composition.materialized.runtimePosture`: the OATS-composed set, what is
178
+ All harnesses record what they actually expose in `instance.json` under
179
+ `composition.materialized.harnessPosture`: the OATS-composed set, what is
180
180
  curtailed, and what remains ambient. The deviation from strict composition is
181
181
  auditable rather than implied.
182
182
 
@@ -42,10 +42,11 @@
42
42
  "additionalProperties": {
43
43
  "type": "object",
44
44
  "additionalProperties": false,
45
- "required": ["runtime"],
45
+ "anyOf": [{ "required": ["harness"] }, { "required": ["runtime"] }],
46
46
  "properties": {
47
- "runtime": { "type": "string", "enum": ["pi", "claude", "codex"], "description": "The harness family this configuration starts; it decides the kernel's own baseline arguments (skills, instructions, task) and how model/yolo are expressed." },
48
- "executable": { "type": "string", "minLength": 1, "description": "The program to run instead of the runtime's default binary: a bare name is looked up on PATH on the execution host; a path containing a slash is resolved against the deployment directory (where this oats-local.yaml lives) when relative. Checked to exist and be executable before any start; never executed just to probe it." },
47
+ "harness": { "type": "string", "enum": ["pi", "claude", "codex"], "description": "The harness this configuration starts (named `runtime` before 0.27.0); it decides the kernel's own baseline arguments (skills, instructions, task) and how model/yolo are expressed." },
48
+ "runtime": { "type": "string", "enum": ["pi", "claude", "codex"], "deprecated": true, "description": "The pre-0.27 name of `harness`, still read (a deprecation warning); both, disagreeing, are refused. `oats launch-config set` writes `harness`." },
49
+ "executable": { "type": "string", "minLength": 1, "description": "The program to run instead of the harness's default binary: a bare name is looked up on PATH on the execution host; a path containing a slash is resolved against the deployment directory (where this oats-local.yaml lives) when relative. Checked to exist and be executable before any start; never executed just to probe it." },
49
50
  "args": { "type": "array", "items": { "type": "string" }, "description": "Extra arguments, each passed literally (no shell interpretation): native configuration files or profiles go here as ordinary arguments." },
50
51
  "env": {
51
52
  "type": "object",
@@ -58,7 +59,7 @@
58
59
  },
59
60
  "description": "Environment for the harness. A string is a literal (non-secret by contract; still redacted in every answer). {fromEnv: NAME} is resolved from the execution host's environment at start time; the reference, never the value, is recorded. A missing reference refuses the start before anything stops."
60
61
  },
61
- "model": { "type": "string", "minLength": 1, "description": "Model for this configuration's runtime; overrides the soul default when this configuration is selected." },
62
+ "model": { "type": "string", "minLength": 1, "description": "Model for this configuration's harness; overrides the soul default when this configuration is selected." },
62
63
  "yolo": { "type": "boolean", "description": "Permission bypass for this configuration; overrides scope and soul defaults when selected." }
63
64
  }
64
65
  }
package/docs/packages.md CHANGED
@@ -286,5 +286,5 @@ says so.
286
286
  replacement (`details.removed` / `details.replacement` in `--json`). There is
287
287
  no installed-capability directory, no config template adoption, no host
288
288
  requirement installer. A manifest's `requires` still describes what must exist
289
- on the host (runtime packages are verified at spawn; host commands are the
289
+ on the host (harness packages are verified at spawn; host commands are the
290
290
  operator's to install).
@@ -0,0 +1,100 @@
1
+ # OATS 0.27.0
2
+
3
+ What starts an instance (pi, claude or codex) is now called its **harness**
4
+ everywhere the kernel used to say `runtime`: in flags, configuration, records,
5
+ JSON and error codes. Nothing already written stops working. The rule is read
6
+ either, write new: every spelling from before 0.27.0 is still read, and the
7
+ next write records the new one. A command that reads an old spelling answers
8
+ one `deprecated-runtime-name` warning, and a later release drops the old
9
+ spellings. See [Upgrading from 0.26](#upgrading-from-026).
10
+
11
+ ## Changed
12
+
13
+ - **runtime → harness.** [The Desktop CLI API](../desktop-cli-api.md#the-harness-rename-feature-harness-oats-0270)
14
+ has the complete table. In short:
15
+ - Flags: `--harness` replaces `--runtime` on `spawn` (and `--preview`),
16
+ `session start|restart` and `launch-config preview`, including their
17
+ `--server` forms. `--runtime` is still accepted, with the warning. The
18
+ two given with different values are refused (`E_BAD_ARGS`).
19
+ - `oats-local.yaml`: a launch configuration names `harness:`. `runtime:` is
20
+ still read, with the warning. Both, disagreeing, is a schema error
21
+ (`E_WORKSPACE_SCHEMA`). `oats launch-config set` writes `harness`.
22
+ - Schedules: a spawn job names `harness`. A job stored with `runtime` is
23
+ read as `harness`, with the warning, and saved in the new name next time.
24
+ Both, disagreeing, makes that job invalid (`E_SCHEDULE_INVALID`).
25
+ `lastRun`/`recentRuns` record `startedHarness` (was `startedRuntime`).
26
+ - Homes: `instance.json` records `harness`, and the launch recipe is version
27
+ **2** (`harness`; version 1 said `runtime`). A home spawned by 0.26.0 is
28
+ read in the new names, with the warning naming the home. It inspects,
29
+ starts, restarts and retires as before, and its next start or restart
30
+ records the new names.
31
+ - `soul.yaml` names `harness:`. `runtime:` is still read, **without** a
32
+ warning, because released capabilities ship it (oats.aweb 1.13.1's agents)
33
+ and an operator cannot fix a provider's file. Both, disagreeing:
34
+ `E_BAD_MANIFEST`. The same holds for a capability manifest's
35
+ `requires[]` harness package (`harness`, or `runtime`, never both).
36
+ - Hooks get `OATS_HARNESS` and `OATS_PREVIOUS_HARNESS` beside
37
+ `OATS_RUNTIME` and `OATS_PREVIOUS_RUNTIME`, with the same values.
38
+ - JSON outputs speak only the new names:
39
+ - `oats version --json` lists `harnesses` (no `runtimes`) and the feature
40
+ `harness`;
41
+ - `harness` replaces `runtime` in the status, inspect, spawn, preview,
42
+ session, launch-config, schedule and event documents;
43
+ - `harnessPackages` and `harnessPosture` replace `runtimePackages` and
44
+ `runtimePosture` in `composition.materialized`;
45
+ - the launch plan's package check (`launch-config preview` `problems[]`)
46
+ is `harness-packages`, and package verification's `loadedBy` is
47
+ `harness-discovery`.
48
+ - Error codes: `E_UNSUPPORTED_HARNESS`, `E_HARNESS_PACKAGE` and
49
+ `E_HARNESS_RESOURCE_MISSING` replace `E_UNSUPPORTED_RUNTIME`,
50
+ `E_RUNTIME_PACKAGE` and `E_RUNTIME_RESOURCE_MISSING`.
51
+ - JSON envelopes may carry `warnings: [...]`, only when there is something
52
+ to say. `oats status --json` carries it beside `problems`. In text mode,
53
+ a warning is one `oats: warning: …` line on stderr.
54
+ - Routed commands (`--server`) speak each host's own vocabulary. A host
55
+ without the `harness` feature (0.26.x and older) is sent `--runtime` and
56
+ `runtime` keys, and its `runtimes` list and `runtime` roster rows are read
57
+ as harnesses.
58
+ - A spawn decision previewed by a 0.26 kernel is `E_DECISION_STALE` at a
59
+ 0.27 apply (the revision covers the key names), with the fresh decision
60
+ attached.
61
+ - Unchanged, because they do not name the harness: the session endpoint's
62
+ `runtimeAuthority`, `runtimeState` and `runtimeError`, the
63
+ `E_RUNTIME_ENDPOINT_*`, `E_RUNTIME_AUTHORITY_MISMATCH` and
64
+ `E_RUNTIME_QUIESCE_FAILED` codes, `capabilityRuntime`, the retirement
65
+ baseline, and oats.okf's `harvest-runtime` setting.
66
+
67
+ ## Desktop
68
+
69
+ - **The Desktop speaks the harness names** on a kernel that declares feature
70
+ `harness` (`--harness`, `harness`/`harnesses`), and the old names on released
71
+ 0.25.8–0.26.x kernels. It reads either spelling everywhere, shows only the
72
+ harness the kernel reports (no `pi` default for an instance that doesn't say),
73
+ and accepts kernels `>=0.25.8 <0.28.0`.
74
+ - **Core capabilities name their origin** (soul, workspace or team) on the soul
75
+ page and the instance sidebar, on a kernel with feature `layers-from`.
76
+ - The unused "the workspace's team settings" origin label is gone (0.26.0's
77
+ teams amendment K stopped emitting it).
78
+
79
+ ## Fixed
80
+
81
+ - **0.26.0's notes said per-workspace personal teams need undeployed aweb
82
+ server support.** The aweb service (0.8.13 and later) and CLI (1.36.8 and
83
+ later) already carry personal enrollment; what remains is oats.aweb 1.15
84
+ adopting it. The bundled oats.aweb is still 1.13.1 (the personal team only);
85
+ the team verbs come with oats.aweb 1.14.1 in a 0.27.x patch.
86
+
87
+ ## Upgrading from 0.26
88
+
89
+ Nothing to do. Old spellings keep working with a `deprecated-runtime-name`
90
+ warning, and a later release drops them. To stop the warning:
91
+
92
+ - write `harness:` for `runtime:` in `oats-local.yaml` launch configurations
93
+ (or re-save them with `oats launch-config set`);
94
+ - pass `--harness` for `--runtime` in scripts;
95
+ - re-save any schedule the warning names (`oats schedule update`). A stored
96
+ job is also rewritten on its next save.
97
+
98
+ A 0.26.0 home stops warning after its next start or restart. A Desktop that
99
+ gates on the `harness` feature reads the new names; an older Desktop reads
100
+ `runtimes` and `runtime` and needs its update.
package/docs/schedules.md CHANGED
@@ -39,7 +39,7 @@ see [Captured definitions](#captured-definitions-removed-in-026).
39
39
  ## Kinds
40
40
 
41
41
  - **spawn** `{id, enabled, cron, tz, kind: "spawn", agent, agentsRoot?,
42
- repo?, backend?, purpose?, task, runtime?, model?, yolo?, wake?}` — every
42
+ repo?, backend?, purpose?, task, harness?, model?, yolo?, wake?}` — every
43
43
  due minute launches one disposable instance of `agent` with the same
44
44
  options `oats spawn` takes. `agentsRoot` names the exact agents root that
45
45
  holds the soul (it must lie inside the workspace and defaults to the
@@ -136,7 +136,7 @@ running}], scheduler: {installed, active, lastTick, maxConcurrent, ...}}`.
136
136
  ## What a run reports
137
137
 
138
138
  `launched` (spawn or command returned), `active` (the instance is running;
139
- a home whose retirement is pending still counts, its runtime may be alive),
139
+ a home whose retirement is pending still counts, its harness may be alive),
140
140
  `ended` (its home is gone), `stopped` (home present, nothing running: needs
141
141
  attention, never removed for you), `launch-failed`, `unknown`, and for wake
142
142
  jobs `delivered`, `started` or `skipped`. The kernel never claims a task
@@ -159,13 +159,13 @@ unknown; check the roster and the host by hand, then
159
159
  slot (or `remove --force` forgets the job).
160
160
 
161
161
  A wake job that starts a stopped home holds a launch slot while that
162
- runtime is starting, active, retiring or unobservable, and releases it when
163
- the runtime is proven stopped (the session start receipt's exit marker for
162
+ harness is starting, active, retiring or unobservable, and releases it when
163
+ the harness is proven stopped (the session start receipt's exit marker for
164
164
  that launch, or a home that no longer has a session) or the home is gone.
165
165
  A persistent home that outlives its process does not keep a slot. Delivering
166
166
  a message to a home that is already running takes no slot. The host tick
167
167
  observes every registered scope first, then admits due jobs in one
168
- host-wide order, least recently launched first (only an actual runtime
168
+ host-wide order, least recently launched first (only an actual harness
169
169
  launch counts; a skipped or pending job keeps its place at the front), so
170
170
  one frequent job in one scope cannot keep the only slot forever. An invalid
171
171
  or malformed definition is reported on that job and the rest of the tick
@@ -177,7 +177,7 @@ execution identity, kind and target cannot
177
177
  change; cron, tz and enabled can. A cold wake persists its slot before
178
178
  the session start runs and keeps it on any start exception, whatever its code
179
179
  (the kernel can refuse while recording, after the session exists); the next
180
- observation releases it once the runtime is proven stopped or absent, one tick
180
+ observation releases it once the harness is proven stopped or absent, one tick
181
181
  at worst.
182
182
  `remove` refuses while the job's instance is still tracked (`--force`
183
183
  forgets the job without stopping anything). Retiring an instance removes the
package/docs/servers.md CHANGED
@@ -25,8 +25,8 @@ oats server list
25
25
  - `--path` names directories to prepend to the remote PATH for every routed
26
26
  command (`~/.local/bin:/opt/pi/bin`). A non-interactive ssh command runs in
27
27
  the login shell's minimal PATH, and the remote kernel's spawn preflight looks
28
- for the runtime binary (`claude`, `pi`, `codex`) there; without this, a
29
- runtime installed under the user's home is "not found" even though it runs
28
+ for the harness binary (`claude`, `pi`, `codex`) there; without this, a
29
+ harness installed under the user's home is "not found" even though it runs
30
30
  fine in an interactive shell on that host.
31
31
  - Registrations live in `~/.oats/servers.json` on this machine, never in a
32
32
  repository scope.
@@ -44,13 +44,13 @@ worktree, identity, launch, retirement. The local side only routes: a local
44
44
  `--task-file` travels as text, every argument is quoted for the remote login
45
45
  shell, and the remote's version and envelope are checked before either
46
46
  mutation (spawn and retire). A spawn is also held to what the remote
47
- advertises: a runtime it does not list (including the soul's own default as
47
+ advertises: a harness it does not list (including the soul's own default as
48
48
  the remote roster reports it), a session backend it lacks, or a launch option
49
49
  such as `--yolo` it does not know is refused with `E_REMOTE_INCOMPATIBLE`
50
50
  saying what was established. A remote that advertises nothing (any kernel
51
51
  before 0.22.2) is assumed to run pi and claude on tmux with no options, and
52
52
  the refusal says so rather than claiming the remote lacks the feature; a soul
53
- the remote roster does not list with a runtime is validated by the remote
53
+ the remote roster does not list with a harness is validated by the remote
54
54
  kernel itself at spawn. `--dir` and `--server` do not combine; the remote
55
55
  workspace comes from the registration.
56
56
 
@@ -68,9 +68,9 @@ compatibility: # optional floors on PACKAGE versions
68
68
  | `compatibility` | `<cap>: <semver range>` checked against the locked package version (`E_COMPATIBILITY`). |
69
69
 
70
70
  Schema: [`soul.schema.json`](soul.schema.json). Not in v2: `kind`, `type`,
71
- `repo`, `runtime`, `model`, `backend`, `yolo`, `launch-config`, `children`,
71
+ `repo`, `harness`, `model`, `backend`, `yolo`, `launch-config`, `children`,
72
72
  `requires`, `source:`, `stores.inherit`. Runtime, model, backend, yolo and the
73
- launch configuration are spawn-time host choices (`--runtime`, `--model`,
73
+ launch configuration are spawn-time host choices (`--harness`, `--model`,
74
74
  `--backend`, `--yolo`, `--launch-config`, or a launch configuration in
75
75
  `oats-local.yaml`), not soul identity: a soul is model-agnostic as an artifact.
76
76
  A child-spawn policy is a spawn flag too (`--no-child-spawns`).
@@ -303,13 +303,13 @@ evidence but never waits for a model or GitHub: independent processing and
303
303
  source-targeted inspection continue after the home disappears.
304
304
 
305
305
  `oats retire <instance> --self` lets an instance retire itself when the human
306
- or briefing says it is done. A live runtime cannot give a stable final
306
+ or briefing says it is done. A live harness cannot give a stable final
307
307
  inspection of its own work, so the calling process inspects, runs, and removes
308
308
  nothing: it records the intent beside its home as
309
309
  `.oats-retire-pending-<instance>.json` and starts a detached completion, then returns so the instance can report final
310
310
  status before its tmux window dies a few seconds later. The completion then
311
311
  retires the instance exactly as an external `oats retire` would: quiesce the
312
- runtime, preserve uncommitted work, run retire hooks, repair lineage, remove
312
+ harness, preserve uncommitted work, run retire hooks, repair lineage, remove
313
313
  the worktree and the home. Success leaves nothing behind: the home and the
314
314
  marker are gone. A failure writes `.oats-retired-<instance>.json` beside the
315
315
  retained home (plus the usual quarantine marker when hooks reported incomplete
@@ -399,7 +399,7 @@ directory; without it, the deployment directory (where `oats-local.yaml` is) is
399
399
  used. No implicit fallback changes the other modes.
400
400
 
401
401
  `--work-dir` and `--branch` are rejected. Canonical instructions, skill
402
- composition, provider trust and runtime preflight still apply. No worktree setup
402
+ composition, provider trust and harness preflight still apply. No worktree setup
403
403
  runs. Retirement preserves nonempty work in verified recovery storage beside the
404
404
  home (`workRecovery.path/work`) before deleting it, including files created by
405
405
  hooks; directory work has no disposable-root exemptions. The work-root cannot be
@@ -469,7 +469,7 @@ they are stated separately:
469
469
  compatibility aliases for the separately published pi extension.
470
470
  - **Lifecycle hooks**: `OATS_INSTANCE_HOME` and `OATS_HOME`, alongside the rest of
471
471
  the hook contract. `OATS_HOME` predates `OATS_INSTANCE_HOME` and is kept because
472
- shipped capability hooks read it; it is **not** exported to runtime sessions.
472
+ shipped capability hooks read it; it is **not** exported to harness sessions.
473
473
 
474
474
  Neither is `OATS_HOME_DIR`, which is the package store root — do not conflate
475
475
  them.
@@ -1,7 +1,7 @@
1
1
  ## Your two directories
2
2
 
3
3
  **`<instance-home>` is where this session starts** — the specific gitignored OATS
4
- instance directory you woke up in, given to your runtime and to every lifecycle
4
+ instance directory you woke up in, given to your harness and to every lifecycle
5
5
  hook as `$OATS_INSTANCE_HOME`. It is not your user home (`~`), not the repository
6
6
  root, and not the work tree. Anything that says "your home" means this directory.
7
7