@awebai/oats 0.25.8 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/bin/oats.mjs +576 -1714
- package/capabilities/oats-authoring/oats-package.json +2 -2
- package/capabilities/oats-authoring/oats.json +2 -2
- package/capabilities/oats-authoring/skills/integration-authoring/SKILL.md +46 -25
- package/capabilities/oats-authoring/skills/soul-craft/SKILL.md +13 -6
- package/capabilities/oats-aweb/bin/oats-aweb.mjs +334 -72
- package/capabilities/oats-aweb/injects/aweb.md +7 -2
- package/capabilities/oats-aweb/lib/binding-wire.mjs +107 -5
- package/capabilities/oats-aweb/lib/captured-native.mjs +1 -1
- package/capabilities/oats-aweb/lib/grant-custody.mjs +38 -0
- package/capabilities/oats-aweb/oats.json +14 -4
- package/capabilities/oats-jira/bin/oats-jira.mjs +4 -4
- package/capabilities/oats-jira/oats.json +2 -2
- package/capabilities/oats-jira/skills/jira-tasks/SKILL.md +6 -3
- package/capabilities/oats-linear/bin/oats-linear-hook.mjs +6 -4
- package/capabilities/oats-linear/oats.json +2 -2
- package/capabilities/oats-linear/skills/linear-tasks/SKILL.md +6 -0
- package/capabilities/oats-okf/bin/oats-okf.mjs +1 -1
- package/capabilities/oats-okf/lib/binding-wire.mjs +1 -1
- package/capabilities/oats-okf/lib/migration.mjs +2 -2
- package/capabilities/oats-okf/lib/sources.mjs +5 -4
- package/capabilities/oats-okf/lib/stores.mjs +40 -9
- package/capabilities/oats-okf/lib/worker.mjs +3 -3
- package/capabilities/oats-okf/oats.json +1 -1
- package/capabilities/oats-review/oats.json +3 -2
- package/docs/capabilities.md +218 -47
- package/docs/capability-manifest.schema.json +13 -4
- package/docs/configuration.md +17 -5
- package/docs/conventions.md +16 -26
- package/docs/design/2026-09-08-expert-assisted-deployment-proposal.md +1 -1
- package/docs/design/2026-09-13-knowledge-and-memory-direction.md +3 -3
- package/docs/design/2026-09-14-portable-souls-and-git-workspaces.md +2 -2
- package/docs/design/2026-09-15-portable-souls-handoff.md +2 -2
- package/docs/design/2026-09-15-portable-souls-implementation.md +1 -1
- package/docs/design/2026-09-20-redesign-program-board.md +2 -2
- package/docs/design/2026-09-23-workspace-module-contracts.md +1 -1
- package/docs/design/2026-09-23-workspace-v2-implementation-plan.md +1 -1
- package/docs/design/2026-09-24-desktop-phase-f-boundary.md +54 -10
- package/docs/design/2026-09-24-phase-d-plan.md +77 -0
- package/docs/design/2026-09-25-teams-contract.md +226 -0
- package/docs/design/README.md +3 -3
- package/docs/design/launch-configurations.md +20 -16
- package/docs/design/operations-contract.md +27 -10
- package/docs/desktop-cli-api.md +546 -264
- package/docs/desktop-instance-start.md +1 -1
- package/docs/desktop.md +7 -13
- package/docs/execution-targets.md +16 -18
- package/docs/first-team.md +14 -17
- package/docs/implementation.md +28 -59
- package/docs/integrations.md +88 -32
- package/docs/knowledge-capability-authoring.md +1 -1
- package/docs/knowledge-reference/package-craft.md +10 -8
- package/docs/knowledge-theory.md +1 -1
- package/docs/knowledge.md +10 -11
- package/docs/layers.md +16 -17
- package/docs/oats-local.schema.json +29 -1
- package/docs/oats-membership.schema.json +5 -3
- package/docs/oats-package.schema.json +2 -2
- package/docs/oats-workspace.schema.json +1 -1
- package/docs/{official-marketplace.md → official-catalog.md} +15 -16
- package/docs/packages.md +75 -52
- package/docs/release-notes/v0.22.0.md +1 -1
- package/docs/release-notes/v0.23.1.md +1 -1
- package/docs/release-notes/v0.25.9.md +23 -0
- package/docs/release-notes/v0.26.0.md +670 -0
- package/docs/schedules.md +48 -126
- package/docs/soul.schema.json +11 -4
- package/docs/souls-and-instances.md +56 -43
- package/docs/workspaces.md +80 -58
- package/injects/instance-boundary.md +1 -1
- package/injects/work-attached.md +1 -1
- package/injects/work-workspace.md +2 -2
- package/lib/{portable-files.mjs → bounded-read.mjs} +6 -6
- package/lib/{portable-values.mjs → canonical-json.mjs} +3 -12
- package/lib/capability-contract.mjs +110 -0
- package/lib/config-data.mjs +2 -2
- package/lib/core.mjs +700 -4824
- package/lib/digest.mjs +12 -0
- package/lib/instance-inspect.mjs +396 -0
- package/lib/instance-lifecycle.mjs +3 -4
- package/lib/instance-resolution.mjs +212 -26
- package/lib/instruction-composition.mjs +0 -20
- package/lib/materialize.mjs +6 -4
- package/lib/operator-dispatch.mjs +33 -13
- package/lib/packages.mjs +25 -190
- package/lib/provider-binding.mjs +4 -2
- package/lib/provider-reasons.mjs +3 -68
- package/lib/resolve.mjs +204 -68
- package/lib/schedule.mjs +97 -272
- package/lib/servers.mjs +13 -13
- package/lib/{portable-shape.mjs → shape.mjs} +4 -3
- package/lib/tree-copy.mjs +44 -0
- package/lib/workspace.mjs +125 -20
- package/package-catalog.json +7 -7
- package/package.json +1 -1
- package/skills/integration-authoring/SKILL.md +48 -40
- package/skills/oats-getting-started/SKILL.md +105 -110
- package/skills/oats-support/SKILL.md +2 -2
- package/skills/soul-craft/SKILL.md +13 -6
- package/bin/oats-pi-sdk-host.mjs +0 -17
- package/docs/2026-09-03-architecture-proposal.md +0 -642
- package/docs/artifact-approvals.schema.json +0 -7
- package/docs/captured-invocation-context.schema.json +0 -7
- package/docs/captured-resolution.schema.json +0 -7
- package/docs/design/package-engine-contract.md +0 -813
- package/docs/design/package-runtime-api.md +0 -588
- package/docs/desktop-succession.md +0 -57
- package/docs/execution-capsule.schema.json +0 -108
- package/docs/first-team-demo.md +0 -92
- package/docs/knowledge-migration.md +0 -147
- package/docs/migration-from-oas.md +0 -103
- package/docs/oats-config.schema.json +0 -172
- package/docs/oats-lock-v3.schema.json +0 -7
- package/docs/oats-lock.schema.json +0 -175
- package/docs/operating-team-migration.md +0 -470
- package/docs/portable.schema.json +0 -2512
- package/docs/provider-check-input.schema.json +0 -7
- package/docs/rebuild-to-v2.md +0 -511
- package/docs/workspace-adoption.md +0 -74
- package/injects/framework-workspace.md +0 -7
- package/injects/local-soul.md +0 -19
- package/injects/oats-portable.md +0 -20
- package/injects/oats.md +0 -11
- package/injects/portable-instance-boundary.md +0 -39
- package/injects/portable-work-directory.md +0 -29
- package/lib/artifact-approvals.mjs +0 -120
- package/lib/artifact-tree.mjs +0 -141
- package/lib/capability-artifacts.mjs +0 -179
- package/lib/capability-execution.mjs +0 -15
- package/lib/capability-inputs.mjs +0 -39
- package/lib/capability-provenance.mjs +0 -231
- package/lib/captured-action-shape.mjs +0 -21
- package/lib/captured-admission-shape.mjs +0 -20
- package/lib/captured-binding-file.mjs +0 -36
- package/lib/captured-dispatch.mjs +0 -66
- package/lib/captured-instance-index.mjs +0 -277
- package/lib/captured-invocation-context.mjs +0 -130
- package/lib/captured-launch-request.mjs +0 -66
- package/lib/captured-operation-process.mjs +0 -15
- package/lib/captured-pi-custody.mjs +0 -29
- package/lib/captured-pi-host.mjs +0 -167
- package/lib/captured-pi-outcome.mjs +0 -172
- package/lib/captured-resolutions.mjs +0 -275
- package/lib/captured-scaffold.mjs +0 -87
- package/lib/captured-selector.mjs +0 -28
- package/lib/captured-session-backend.mjs +0 -52
- package/lib/captured-source-receipt-file.mjs +0 -72
- package/lib/helper-injection-policy.mjs +0 -104
- package/lib/legacy-lock-codec.mjs +0 -106
- package/lib/manifest-settings.mjs +0 -84
- package/lib/package-closure.mjs +0 -48
- package/lib/package-materialization.mjs +0 -83
- package/lib/pi-sdk-host.mjs +0 -229
- package/lib/portable-artifacts.mjs +0 -115
- package/lib/portable-choices.mjs +0 -82
- package/lib/portable-composition.mjs +0 -136
- package/lib/portable-digest.mjs +0 -105
- package/lib/portable-identity.mjs +0 -40
- package/lib/portable-lock.mjs +0 -117
- package/lib/portable-onboarding-request.mjs +0 -49
- package/lib/portable-onboarding.mjs +0 -256
- package/lib/portable-package-preparation.mjs +0 -188
- package/lib/portable-policy.mjs +0 -44
- package/lib/portable-soul.mjs +0 -42
- package/lib/portable-state.mjs +0 -80
- package/lib/prepare-composition.mjs +0 -170
- package/lib/prepared-bindings.mjs +0 -92
- package/lib/prepared-resources.mjs +0 -127
- package/lib/provider-binding-broker.mjs +0 -65
- package/lib/provider-binding-wire.mjs +0 -116
- package/lib/readiness.mjs +0 -225
- package/lib/repository-observation.mjs +0 -226
- package/lib/resolution-shape.mjs +0 -393
- package/lib/schedule-capsule.mjs +0 -206
- package/lib/soul-constraints.mjs +0 -40
- package/lib/source-projection.mjs +0 -84
- package/lib/source-spec.mjs +0 -189
- package/lib/workspace-definition.mjs +0 -126
- package/lib/workspace-discovery.mjs +0 -146
- package/skills/oats/SKILL.md +0 -162
- package/skills/oats-config/SKILL.md +0 -164
- package/skills/oats-packages/SKILL.md +0 -184
- package/skills/oats-portable/SKILL.md +0 -115
- package/skills/oats-portable-artifacts/SKILL.md +0 -63
|
@@ -0,0 +1,670 @@
|
|
|
1
|
+
# OATS 0.26.0
|
|
2
|
+
|
|
3
|
+
The workspace model is the only model the kernel knows ("v2 becomes the
|
|
4
|
+
classic"). The 0.24-era classic path is removed, not flagged: a 0.24.x kernel
|
|
5
|
+
keeps running 0.24.x deployments, and a 0.25.x deployment is already v2
|
|
6
|
+
(the 0.24 → 0.25 rebuild guide is removed in this release; see
|
|
7
|
+
[Upgrading from 0.25](#upgrading-from-025)).
|
|
8
|
+
|
|
9
|
+
## Removed
|
|
10
|
+
|
|
11
|
+
- **The captured/portable path** (0.24–0.25's `oats prepare`, captured
|
|
12
|
+
resolutions, `--deployment --resolution` dispatch, the pi SDK host and
|
|
13
|
+
versioned schedules; lead decisions on (e)). Nothing on the workspace path
|
|
14
|
+
used it, as coverage of the v2 flows showed. What is left of it is typed
|
|
15
|
+
refusals, none falling back to the workspace path:
|
|
16
|
+
- The selectors `--deployment`, `--resolution` and `--artifact-set`, and an
|
|
17
|
+
inherited `OATS_DEPLOYMENT` / `OATS_RESOLUTION`, are refused by every
|
|
18
|
+
command except `version` (`E_UNSUPPORTED_MODE`, `details.selector` or
|
|
19
|
+
`details.inherited`). That includes the captured `oats trust
|
|
20
|
+
--deployment|--artifact-set`.
|
|
21
|
+
- `oats prepare` and `oats inspect --request` are removed verbs
|
|
22
|
+
(`E_UNKNOWN_COMMAND`, `details: {removed, replacement}`): `oats onboard` /
|
|
23
|
+
`oats sync` set a workspace up, and `oats spawn <soul> --preview` shows
|
|
24
|
+
what a spawn would resolve.
|
|
25
|
+
- `oats version --json` no longer carries `capturedDispatchApi` or
|
|
26
|
+
`capturedDispatchActions`.
|
|
27
|
+
- **Captured homes** (an `instance.json` recording `executionBinding`,
|
|
28
|
+
`incarnationId` or `captured`) have no 0.26 runtime. `oats status` and
|
|
29
|
+
`oats doctor` report them once as the problem **`legacy-captured-home`**
|
|
30
|
+
(JSON `problems[]`: `{instances, homes, message}`). Session start/restart,
|
|
31
|
+
`inspect|readiness|operation --home` and in-home commands refuse them
|
|
32
|
+
(`E_UNSUPPORTED_MODE`, `details: {home, captured: true}`). **`oats retire`
|
|
33
|
+
works, but their captured retire hooks do not run:** the result's
|
|
34
|
+
`warnings[]` (also printed by the human output) names each capability whose
|
|
35
|
+
spawn hook ran, since identities/memberships it created are not revoked —
|
|
36
|
+
remove them with the provider's own tooling.
|
|
37
|
+
- **Captured schedule definitions** (`definitionVersion`, `recurrencePolicy`,
|
|
38
|
+
`execution`, `preparation`) are refused by `schedule add|update`
|
|
39
|
+
(`E_SCHEDULE_INVALID`, the key as `field`), locally and before any
|
|
40
|
+
`--server` forwarding. A command argv carrying a captured selector is
|
|
41
|
+
refused too. A stored one is `invalid` on its own job and never runs, and a
|
|
42
|
+
captured attempt or job lock left by 0.25 is reported on its job and never
|
|
43
|
+
run or adopted: `oats schedule remove --force <id>` clears it (a held lock
|
|
44
|
+
keeps its launch slot until then). The run outcome `blocked` is no longer
|
|
45
|
+
produced.
|
|
46
|
+
- **Manifest keys:** `helperInjection` and hook `inputs` are accepted and
|
|
47
|
+
ignored (existing manifests still load).
|
|
48
|
+
- **Public core exports removed with it** (no in-repo consumer):
|
|
49
|
+
`capabilityArtifactIntegrity`, `OATS_LOCK_FILE`, `CAPABILITIES_DIRNAME`,
|
|
50
|
+
`INSTALLED_SUBDIR`, `CAPABILITY_ID_RE`, `isMaterializedCapabilityId`,
|
|
51
|
+
`capabilityIdViolation`, `CAPABILITY_INSTALLATION_FILE`,
|
|
52
|
+
`normalizePackagePath`, `validateLockEntry`, `validateCapabilityLockEntry`,
|
|
53
|
+
`verifyCapabilityInstallation`, `loadPackageManifestAt`,
|
|
54
|
+
`assertCapabilitySelfContained`, `materializeCapabilityDeps`,
|
|
55
|
+
`platformVariantLockPackages`, `isCanonicalTemplatePath`, and every
|
|
56
|
+
captured/portable export (`startCapturedInstanceSession`,
|
|
57
|
+
`prepareCapturedComposition`, `loadCapturedDispatch`, …).
|
|
58
|
+
- **Schemas removed:** `portable`, `captured-resolution`,
|
|
59
|
+
`captured-invocation-context`, `execution-capsule`, `artifact-approvals`,
|
|
60
|
+
`oats-lock-v3` (the captured *selection* lock, never the workspace lock) and
|
|
61
|
+
`oats-lock` (lockfileVersion 2), plus `provider-check-input` (the captured
|
|
62
|
+
check request; the workspace readiness request is documented in
|
|
63
|
+
[capabilities](../capabilities.md#readiness-check-bindingcheck)). The design
|
|
64
|
+
notes `package-engine-contract.md` and `package-runtime-api.md` are deleted.
|
|
65
|
+
- Errors from kernel metadata reads say "metadata file", not "portable
|
|
66
|
+
metadata".
|
|
67
|
+
- **Kernel skills and injects** (human decision on D7): `oats-portable`,
|
|
68
|
+
`oats-portable-artifacts` and the injects `oats-portable`,
|
|
69
|
+
`portable-instance-boundary` and `portable-work-directory` are deleted, and so
|
|
70
|
+
are the kernel's own **`oats` skill** and **`injects/oats.md`** ("You run on
|
|
71
|
+
OATS"): the `oats.core` capability (`oats.framework` package, the workspace
|
|
72
|
+
default) ships the operating skills (`oats-operate`, `oats-souls`) and that
|
|
73
|
+
briefing, and the workspace path already composed only its copy. A soul
|
|
74
|
+
without `oats.core` gets no OATS operating instructions; `oats doctor --soul`
|
|
75
|
+
says so. The kernel keeps `instance-boundary`, the `work-*` briefings and the
|
|
76
|
+
ambient `oats-getting-started`.
|
|
77
|
+
|
|
78
|
+
- **Package approval** (human decision, 2026-09-24). People install a package
|
|
79
|
+
only when they trust it: declaring it in the workspace's `packages:` IS the
|
|
80
|
+
trust decision, so there is no second, per-version approval step.
|
|
81
|
+
- `oats sync` resolves, fetches, verifies integrity, writes the lock and exits
|
|
82
|
+
`0` on success. No exit `2` for pending approvals, no interactive prompt, no
|
|
83
|
+
`approvalNeeded` in the report and none on `changes[]` rows.
|
|
84
|
+
`oats sync --approve …` is `E_BAD_ARGS` naming the decision.
|
|
85
|
+
- `oats onboard` has no approval-pending outcome and no "approve first" hint.
|
|
86
|
+
- The lock (v3) drops the per-entry `approved` record. A lock that still
|
|
87
|
+
carries it is read with the field ignored, and the next write drops it.
|
|
88
|
+
**A kernel before 0.26.0 cannot read a lock 0.26.0 wrote** (`E_LOCK_SCHEMA`
|
|
89
|
+
on the missing `approved`): keep every kernel that reads one deployment on
|
|
90
|
+
0.26.0 or later.
|
|
91
|
+
- The lock still pins each package to its exact commit and content integrity.
|
|
92
|
+
`oats sync` refuses a moved tag, drifted content and a lock whose capability
|
|
93
|
+
list no longer matches the package (`E_PACKAGE_INTEGRITY`) —
|
|
94
|
+
reproducibility, not approval.
|
|
95
|
+
**Where integrity is checked:** `oats sync` recomputes each package's
|
|
96
|
+
content digest and refuses drift. At spawn, the kernel checks the lock's
|
|
97
|
+
capability list against the package and trusts the locked commit plus
|
|
98
|
+
materialize's fetch-versus-copy self-check. The lock's integrity is
|
|
99
|
+
recorded in each module's `from`, not recomputed per spawn. (The removed
|
|
100
|
+
per-spawn executables-digest check was an approval binding, not an
|
|
101
|
+
integrity guarantee.)
|
|
102
|
+
- Spawn, `--preview` and operator dispatch never raise `E_PACKAGE_UNAPPROVED`;
|
|
103
|
+
the executables-digest gate is gone. At spawn a package capability must come
|
|
104
|
+
from a package the workspace **still declares** (a stale lock entry for a
|
|
105
|
+
package removed from `packages:` is `E_PACKAGE_MISSING { reason:
|
|
106
|
+
"undeclared" }` until `oats sync`), and the lock's capability list must match
|
|
107
|
+
what the package declares at the locked commit (`E_PACKAGE_INTEGRITY { why:
|
|
108
|
+
"capabilities" }`). A package capability agent is found only in a declared
|
|
109
|
+
package.
|
|
110
|
+
- `oats workspace status` loses its `approval` object and column; `oats
|
|
111
|
+
capabilities` package rows lose `approved`; `oats doctor` prints each locked
|
|
112
|
+
package's integrity instead of its approval.
|
|
113
|
+
- `oats version --json` advertises `packages-no-approval`. `syncApi`,
|
|
114
|
+
`workspaceStatusApi` and `capabilitiesApi` are NOT bumped: a consumer that
|
|
115
|
+
reads the removed fields gates on this feature string.
|
|
116
|
+
- **The `soul` link in instance homes.** A home no longer carries
|
|
117
|
+
`<home>/soul`: its composed `AGENTS.md` already holds the soul's
|
|
118
|
+
instructions. The soul directory an instance incarnates is recorded as
|
|
119
|
+
`instance.json` `soulDir` (a workspace soul's per-commit copy
|
|
120
|
+
`<deployment>/agents/<soul>/souls/<commit12>`, or the read-only soul inside a
|
|
121
|
+
capability package) and is handed to every classic lifecycle hook — spawn,
|
|
122
|
+
launch, retire — and to every capability command dispatched inside a home as
|
|
123
|
+
`OATS_SOUL`. Launch
|
|
124
|
+
and retire hooks, and in-home commands such as `oats okf harvest`, previously
|
|
125
|
+
received no `OATS_SOUL`; `oats operation run`
|
|
126
|
+
previously handed the swappable `agents/<soul>/soul` pointer. `oats session
|
|
127
|
+
recompose` reads the recorded `soulDir`. A spawn that is rolled back into
|
|
128
|
+
quarantine records the soul in its cleanup descriptor, so a retried retire
|
|
129
|
+
hook sees the spawn's soul. A capability command dispatched with no recorded
|
|
130
|
+
soul gets no `OATS_SOUL`, never one inherited from the invoking process.
|
|
131
|
+
- **Homes spawned before 0.26.0** record no `soulDir`. They keep their
|
|
132
|
+
existing `soul` link (0.26.0 neither reads nor removes it). Their retire
|
|
133
|
+
hooks get the soul pointer `agents/<soul>/soul` (today's soul, not
|
|
134
|
+
necessarily the spawn's commit). They are degraded: their launch hooks and
|
|
135
|
+
in-home commands get no `OATS_SOUL` (a provider that requires it, such as
|
|
136
|
+
oats.okf 2.1.5, refuses with `E_OATS_SOUL_MISSING`), and `oats session
|
|
137
|
+
recompose` refuses them (`E_SOUL_UNKNOWN`). Re-spawn to get a recorded
|
|
138
|
+
`soulDir`.
|
|
139
|
+
|
|
140
|
+
- **Local souls and `local-agents/`.** A soul is a member repository's
|
|
141
|
+
`souls/<name>` (`soul.yaml` + `AGENTS.md`); there are no machine-local souls.
|
|
142
|
+
- **`oats create` is removed**: `E_UNKNOWN_COMMAND` naming the replacement
|
|
143
|
+
(author `souls/<name>/soul.yaml` + `AGENTS.md` in a member repository, then
|
|
144
|
+
`oats sync`). `--local`, `--type` and the `.gitignore` injection went with it.
|
|
145
|
+
- **`oats spawn --instructions-file` and `--def-file`** (which wrote a local
|
|
146
|
+
soul, including from a `.claude/agents` definition) are refused with
|
|
147
|
+
`E_BAD_ARGS` naming the same replacement. `oats status` no longer lists
|
|
148
|
+
importable definitions.
|
|
149
|
+
- The kernel no longer composes the local-soul instruction block.
|
|
150
|
+
- **`soul-scaffold` hooks are no longer run** (souls are authored in member
|
|
151
|
+
repositories); manifests may still declare it until providers drop it.
|
|
152
|
+
- **Capability-defined agents** (a package's or member module's `agents/`,
|
|
153
|
+
such as the OKF harvester) now home at
|
|
154
|
+
`<deployment>/agents/<agent>/instances/<name>`, like souls. That directory
|
|
155
|
+
holds only `instances/`. A name that is both a workspace soul and a
|
|
156
|
+
capability agent stays `E_SOUL_AMBIGUOUS`.
|
|
157
|
+
- The agents root is found only as the closest `agents/` (or
|
|
158
|
+
`PI_AGENTS_ROOT`); a `local-agents/` beside it no longer locates one.
|
|
159
|
+
- **OAS scope probes.** `oats doctor` no longer looks for un-migrated OAS
|
|
160
|
+
scope files, and the dead `docs/migration-from-oas.md` links went with the
|
|
161
|
+
probe.
|
|
162
|
+
- **The installed tier.** `oats doctor` loses its installed-packages section.
|
|
163
|
+
The restore, remove, lock-migration and installed config-template readers
|
|
164
|
+
are deleted with it.
|
|
165
|
+
- **Classic verbs** (lead decision 3). Each answers a typed refusal naming
|
|
166
|
+
its replacement:
|
|
167
|
+
- `oats type` and `oats soul set` are removed verbs (`E_UNKNOWN_COMMAND`).
|
|
168
|
+
A soul is edited in its member repository (`soul.yaml` + `AGENTS.md`),
|
|
169
|
+
then `oats sync`; per-spawn choices are spawn flags or a launch
|
|
170
|
+
configuration. `soul` no longer routes with `--server`.
|
|
171
|
+
- `oats session recompose` is `E_UNKNOWN_COMMAND`, and the
|
|
172
|
+
`session-recompose` feature is no longer advertised. The refresh path is
|
|
173
|
+
a re-spawn: an instance never changes under itself.
|
|
174
|
+
- `oats status --team` is `E_BAD_ARGS`: `oats status` in the deployment
|
|
175
|
+
lists every instance, and `oats workspace status` shows the members.
|
|
176
|
+
- **The classic answers of `oats inspect`, `oats readiness` and `oats
|
|
177
|
+
operation run`** (lead decision 4). There is no v1 shape any more. With no
|
|
178
|
+
`oats-local.yaml` in reach and no `--home` they answer `E_LOCAL_MISSING`; a
|
|
179
|
+
`--home` whose `instance.json` records no `modules` (spawned by an earlier
|
|
180
|
+
kernel) answers `E_UNSUPPORTED_MODE` (re-spawn it from the deployment); an
|
|
181
|
+
unreadable `--home` answers `E_SESSION_UNKNOWN`. `--verify-signatures` is
|
|
182
|
+
always `E_BAD_ARGS`, and the signature verifier is deleted.
|
|
183
|
+
|
|
184
|
+
- **`oats-config.yaml` and the scope configuration chain** (lead decisions
|
|
185
|
+
c3 1–7, 9). The kernel reads no `oats-config.yaml`. One found between a
|
|
186
|
+
command's directory and its deployment (the directory holding
|
|
187
|
+
`oats-local.yaml`) is refused, `E_CONFIG_BROKEN` (`reason:
|
|
188
|
+
"legacy-config"`), naming where each key went; with no `oats-local.yaml` in
|
|
189
|
+
reach, `E_LOCAL_MISSING` names the file as a 0.25 deployment's.
|
|
190
|
+
`docs/oats-config.schema.json` is deleted (below). Each key:
|
|
191
|
+
- **`capabilities:`** (`layers:`, `additive:`, targets, `from:`,
|
|
192
|
+
`injection-override:`) and **`agent-types:`**: a soul's capabilities are
|
|
193
|
+
the workspace's resolution — `oats-workspace.yaml` `defaults:` and each
|
|
194
|
+
soul's `soul.yaml` `capabilities:` / slot keys, then `oats sync`.
|
|
195
|
+
- **`team:`**: teams are `oats-workspace.yaml` `teams:` and a soul's
|
|
196
|
+
`team:`. Hooks get the workspace facts only: `OATS_TEAM_SCOPE` (the
|
|
197
|
+
deployment), `OATS_TEAM_ID` (the messaging payload's `team`),
|
|
198
|
+
`OATS_TEAM_LABEL`, `OATS_WORKSPACE_NAME`, `OATS_WORKSPACE_KEY`;
|
|
199
|
+
`OATS_TEAM_NAME` is always empty. Operator-level capability commands get
|
|
200
|
+
the same five.
|
|
201
|
+
- **`work-modes:`**: a soul's `work:` and the spawn flags decide the mode. A
|
|
202
|
+
worktree `setup:` script no longer runs (run it yourself, or from a
|
|
203
|
+
capability's spawn hook); `retirement-disposable:` is gone with it (a
|
|
204
|
+
capability's manifest `retirement.disposable` still applies).
|
|
205
|
+
- **`agents-md-injection:`**: removed. Instructions come from the soul and
|
|
206
|
+
its modules' injects.
|
|
207
|
+
- **`skill-overrides:`**: removed. A duplicate skill name is
|
|
208
|
+
`E_SKILL_DUPLICATE`; there is no override.
|
|
209
|
+
- **Scope `yolo:`**: removed. Yolo is `--yolo` on `oats spawn`, `session
|
|
210
|
+
start` and `session restart`, or a launch configuration's `yolo`.
|
|
211
|
+
- **`launch-configs:`**: moved to `oats-local.yaml` (see Changed).
|
|
212
|
+
- **`oats:` `injection-override:`**: removed with the kernel's operational
|
|
213
|
+
block (below).
|
|
214
|
+
- **Scheduling a capability agent by name.** A `kind: "spawn"` schedule's
|
|
215
|
+
`agent` is a soul under the deployment's `agents/` root only; the fallback
|
|
216
|
+
to a capability-defined agent (a harvester, a reviewer) is gone with the
|
|
217
|
+
config chain (`E_SCHEDULE_INVALID`, `agent: no soul named …`). Schedule what
|
|
218
|
+
spawns it instead: a `kind: "command"` job running the capability's own
|
|
219
|
+
command (for example `oats okf harvest --soul <soul>`), or a
|
|
220
|
+
`kind: "operation"` job running the provider operation on the anchor home.
|
|
221
|
+
- **Spawning without a workspace deployment.** `oats spawn` with no
|
|
222
|
+
`oats-local.yaml` in reach is `E_LOCAL_MISSING` naming `oats onboard`
|
|
223
|
+
(0.25 answered `E_NO_DEPLOYMENT`, which now means only a deployment whose
|
|
224
|
+
`agents/` root is missing); the kernel's `spawnInstance` without a prepared resolution refuses the same
|
|
225
|
+
way (`spawnInstanceAsync` with `prepared` is the one spawn).
|
|
226
|
+
- **v1 soul fields.** A soul's `runtime`, `model`, `backend`, `repo`, `yolo`,
|
|
227
|
+
`launch-config`, `children` and `requires:` are not read (the v2 soul schema
|
|
228
|
+
already refuses them at discovery; lead decision c3 Q6). They are spawn and
|
|
229
|
+
host choices: `--runtime`, `--model`, `--backend`, `--repo`, `--yolo`,
|
|
230
|
+
`--launch-config` / `oats-local.yaml` `launch-configs:`, and
|
|
231
|
+
`--allow-child-spawns` / `--no-child-spawns` (a recorded child-spawn policy's
|
|
232
|
+
origin is `spawn-option` or `default`, never `soul`). An attached instance
|
|
233
|
+
works in its work tree owner's recorded repository. A capability agent's own
|
|
234
|
+
`soul.yaml` (for example `oats.review`'s reviewer) still names its default
|
|
235
|
+
`runtime`, `model` and `work`.
|
|
236
|
+
- **The kernel's operational block and bundled skills** (lead decision c3 9).
|
|
237
|
+
A soul whose resolution has no `oats.core` or `oats.setup` module no longer
|
|
238
|
+
gets the kernel's "You run on OATS" block or the `oats`, `oats-config` and
|
|
239
|
+
`oats-packages` skills copied into its home; operational knowledge is the
|
|
240
|
+
`oats.core` / `oats.setup` capabilities'. The `skills/oats-config` and
|
|
241
|
+
`skills/oats-packages` directories are deleted.
|
|
242
|
+
- **Session start, restart and capability commands on homes from an earlier
|
|
243
|
+
kernel** (lead decision c3 Q2). A home whose `instance.json` records no
|
|
244
|
+
`modules` answers `E_UNSUPPORTED_MODE` ("re-spawn it from the deployment").
|
|
245
|
+
**`oats retire` still works on it**: no retire hook runs (the home records
|
|
246
|
+
none), and the result's `warnings` says so.
|
|
247
|
+
- **The conversion of a home that predates launch recipes** (lead decision
|
|
248
|
+
c3c). `oats launch-config preview --home` still describes such a home as
|
|
249
|
+
recorded (`selection.source: "frozen-command"`). Under a selection
|
|
250
|
+
(`--runtime`, `--launch-config`, `--model`, `--yolo`/`--no-yolo`) it answers
|
|
251
|
+
`E_LAUNCH_LEGACY` ("re-spawn it from the deployment; nothing was changed")
|
|
252
|
+
instead of converting the recorded command.
|
|
253
|
+
- **Classic `oats doctor`, schedule scope and team roots.** `oats doctor` is
|
|
254
|
+
the workspace-model doctor only (`E_LOCAL_MISSING` with no deployment in
|
|
255
|
+
reach; `--dir` is honoured). A schedule belongs to the deployment directory:
|
|
256
|
+
with none in reach, `oats schedule` is `E_LOCAL_MISSING`, never an ambient
|
|
257
|
+
`OATS_ROOT` / `PI_AGENTS_ROOT` scope. A deployment has one agents root; the
|
|
258
|
+
cross-repository team roots (and `--parent` across them) are gone.
|
|
259
|
+
- **The framework repository's root `oats-config.yaml`** and its only reader,
|
|
260
|
+
`injects/framework-workspace.md`. The kernel refuses an `oats-config.yaml`
|
|
261
|
+
between a command's directory and its deployment, so every instance whose
|
|
262
|
+
work tree is a checkout of this repository failed every `oats` command; the
|
|
263
|
+
root `oats-workspace.yaml` and `oats-membership.yaml` are the repository's
|
|
264
|
+
config, and `scripts/validate-project.mjs` refuses a root `oats-config.yaml`.
|
|
265
|
+
**Consequence:** a classic deployment rooted at a checkout of this repository
|
|
266
|
+
(its root holds `agents/` and a 0.24/0.25 kernel reads the root
|
|
267
|
+
`oats-config.yaml`) can spawn no new instance from that root once it pulls
|
|
268
|
+
this change. Existing homes keep running and retire normally; the rebuild is
|
|
269
|
+
`oats-local.yaml` + `oats onboard` on 0.26.0.
|
|
270
|
+
- **The classic-era guides:** `docs/rebuild-to-v2.md` (the 0.24 → 0.25 rebuild
|
|
271
|
+
guide) and its skill form, `oats.setup`'s `oats-rebuild`;
|
|
272
|
+
`docs/operating-team-migration.md`; `docs/knowledge-migration.md` (OKF v1 →
|
|
273
|
+
v2 for 0.23); `docs/workspace-adoption.md`; `docs/first-team-demo.md`;
|
|
274
|
+
`docs/2026-09-03-architecture-proposal.md`. The catalog-pinned workspace
|
|
275
|
+
example moved to [packages.md](../packages.md#declaring-packages-two-forms-in-one-place),
|
|
276
|
+
where a test keeps its pins equal to `package-catalog.json`.
|
|
277
|
+
- **`docs/oats-config.schema.json`**, the record of what 0.25 read.
|
|
278
|
+
- **Kernel helpers of the v1 catalog migration:** `describeOfficialCatalog`
|
|
279
|
+
(with its `oats install` acquire argv and approval notes) and
|
|
280
|
+
`officialCapabilityPackage` (the `marketplace:` → package mapping);
|
|
281
|
+
`officialCatalogFile` names the effective catalog file. `findRoot` no longer
|
|
282
|
+
treats an `oats-config.yaml` without `agents/` as a package-only deployment
|
|
283
|
+
root; a deployment without `agents/` gets `ensureRoot`'s `oats-local.yaml`
|
|
284
|
+
remedy.
|
|
285
|
+
- **The repository's root `log.md`** (the stale 0.24.2 working log).
|
|
286
|
+
- **The "marketplace" name** for the official list: `docs/official-marketplace.md`
|
|
287
|
+
is [official-catalog.md](../official-catalog.md), and the catalog's `policy`
|
|
288
|
+
field points there.
|
|
289
|
+
|
|
290
|
+
## Known limitations
|
|
291
|
+
|
|
292
|
+
- **A scheduled wake's session start uses the spawn-time teams**
|
|
293
|
+
(`OATS_TEAMS_SOURCE=recorded`), because the scheduler reads no remote. Its
|
|
294
|
+
launch hook therefore leaves no team. The next operator
|
|
295
|
+
`oats session start|restart`, or messaging command, is live.
|
|
296
|
+
|
|
297
|
+
- **Joining teams beyond the personal one needs a later oats.aweb.** 0.26.0
|
|
298
|
+
bundles and pins **oats.aweb 1.13.1**: every instance gets its primary aweb
|
|
299
|
+
identity in the personal team (the aweb root's active team, or
|
|
300
|
+
`settings.oats.aweb.team`; see teams amendment K under Changed), and the
|
|
301
|
+
kernel hands the provider `OATS_TEAMS`, but 1.13.1 joins no further team.
|
|
302
|
+
The team verbs (`messaging:teams|join|leave`, and `join=` at spawn) arrive
|
|
303
|
+
with oats.aweb 1.14.x, pinned in a 0.26.x patch. There, joined teams **poll**
|
|
304
|
+
(their mail is read between tasks); live receive for joined teams is planned
|
|
305
|
+
for oats.aweb 1.15.
|
|
306
|
+
- **A per-workspace personal team** (one personal team per person per
|
|
307
|
+
workspace) needs aweb server support that is not yet deployed. Until then,
|
|
308
|
+
"personal" is the person's active aweb team, shared across that person's
|
|
309
|
+
workspaces.
|
|
310
|
+
|
|
311
|
+
## Upgrading from 0.25
|
|
312
|
+
|
|
313
|
+
- **Retire classic instances with 0.25, then onboard the deployment with
|
|
314
|
+
0.26.** A 0.25 deployment configured by `oats-config.yaml` is refused by
|
|
315
|
+
0.26.0 (`E_CONFIG_BROKEN` / `E_LOCAL_MISSING`, above). With the 0.25 kernel,
|
|
316
|
+
retire its instances; then, with 0.26.0, write the deployment's
|
|
317
|
+
`oats-local.yaml` (`oats onboard`), move what the old file declared into
|
|
318
|
+
`oats-workspace.yaml` and each soul's `soul.yaml`, delete `oats-config.yaml`,
|
|
319
|
+
and run `oats sync`. Homes left behind still retire under 0.26.0, but
|
|
320
|
+
**no retire hook runs for them** (a pre-workspace home records no capability
|
|
321
|
+
hooks): a messaging identity the 0.25 retire hook would have revoked stays
|
|
322
|
+
live. Retire classic instances with the 0.25 kernel first, or revoke their
|
|
323
|
+
identities by hand after retiring them with 0.26.0.
|
|
324
|
+
- **Retire capability-agent instances before upgrading.** Instances homed
|
|
325
|
+
under `<deployment>/local-agents/` (running knowledge harvesters, for
|
|
326
|
+
example) are not managed by 0.26.0: it never reads, spawns into or retires
|
|
327
|
+
from that directory, and only detects it (onboarding refuses into a
|
|
328
|
+
directory that holds one). Retire them with the 0.25 kernel first, or accept that
|
|
329
|
+
they are orphaned. While the directory exists, `oats status` and
|
|
330
|
+
`oats doctor` report it once as the problem **`legacy-local-agents`** (JSON
|
|
331
|
+
`problems[]`), naming the instances found there. Delete the directory once
|
|
332
|
+
they are stopped.
|
|
333
|
+
|
|
334
|
+
- **Wake needs aw 1.36.5 or later, and a daemon restart.** Scheduled and
|
|
335
|
+
mail-driven wakes were verified end to end on aw 1.36.8 for session-delivery
|
|
336
|
+
homes. After upgrading aw, restart the host's wake daemon so it re-registers.
|
|
337
|
+
|
|
338
|
+
- **Captured homes and captured schedules** (from 0.24–0.25's captured path):
|
|
339
|
+
retire each captured home — 0.26.0 retires it, but none of its captured
|
|
340
|
+
retire hooks runs, so revoke the messaging identities and memberships named
|
|
341
|
+
in the retire warnings with the provider's own tooling — and re-spawn the soul
|
|
342
|
+
from the deployment. Remove each captured schedule job
|
|
343
|
+
(`oats schedule remove --force <id>`) and re-add it without the captured keys.
|
|
344
|
+
|
|
345
|
+
## Added
|
|
346
|
+
|
|
347
|
+
- **Private capabilities are listed as repo-owned** (human decision,
|
|
348
|
+
2026-09-25). `oats capabilities` (and `--json`) now lists a member
|
|
349
|
+
capability whose manifest says `private: true`, with `private: true` on its
|
|
350
|
+
row; the human table marks it "(repo-owned)". Enforcement is unchanged: only
|
|
351
|
+
souls of its own repository can use it (`E_CAPABILITY_PRIVATE`). `oats sync`'s
|
|
352
|
+
"· N private" count is of these capabilities. Feature
|
|
353
|
+
`capabilities-private` in `oats version --json`; the Desktop shows its "Repo
|
|
354
|
+
owned" section only when it is present.
|
|
355
|
+
- **`oats spawn <soul> --name <slug>`** (human decision, 2026-09-24): an
|
|
356
|
+
explicit, unprefixed instance name. The name is exactly `<slug>`, with no
|
|
357
|
+
`<soul>-` prefix. Derived naming (`--purpose`, `<soul>-<n>`) stays the
|
|
358
|
+
default.
|
|
359
|
+
- `--name` and `--purpose` are mutually exclusive (`E_BAD_ARGS`).
|
|
360
|
+
- The name is never rewritten: a non-slug, or a soul name of the deployment,
|
|
361
|
+
is `E_INSTANCE_NAME_INVALID`.
|
|
362
|
+
- A name that any soul of the deployment already holds, or that a live tmux
|
|
363
|
+
window carries, is `E_INSTANCE_NAME_TAKEN`; never a silent `-2`.
|
|
364
|
+
- `--preview` reports the final name and the same refusals, and
|
|
365
|
+
`--expect-decision` binds the name.
|
|
366
|
+
- Feature `spawn-name`.
|
|
367
|
+
- **Instance names are at most 64 characters**, explicit and derived (the
|
|
368
|
+
messaging alias allows 1–64). A longer name is `E_INSTANCE_NAME_INVALID` in
|
|
369
|
+
preview and apply, and is never truncated. A derived name that would exceed
|
|
370
|
+
64 (a long purpose, or the `-2` suffix on a long one) is refused, naming the
|
|
371
|
+
purpose to shorten. A spawn schedule whose run names
|
|
372
|
+
(`<agent>-<purpose|id>-<YYYYMMDDHHMM>`) would exceed 64 is refused when it is
|
|
373
|
+
saved (`E_SCHEDULE_INVALID`). Previously such a name passed the kernel and
|
|
374
|
+
failed only at the messaging join.
|
|
375
|
+
- **The retire summary names what a recovery copied and what it cost.** A
|
|
376
|
+
workspace-model worktree has no disposable declaration, so its ignored build
|
|
377
|
+
outputs (`node_modules/`, `build/` …) are copied to recovery with the
|
|
378
|
+
uncommitted work: safe, not clean. A recovery (`workRecovery` /
|
|
379
|
+
`workRecoveries[]` under `--json`, and its `recovery.json`) now carries
|
|
380
|
+
`outputs: { paths: [{ path, bytes }], bytes }` (the untracked and ignored
|
|
381
|
+
paths, or a directory's work entries, grouped by top-level entry, largest
|
|
382
|
+
first) and its own `bytes`; the text summary prints the recovery's size and
|
|
383
|
+
`copied outputs: node_modules/ (412.0 MiB), … — <total> in total`.
|
|
384
|
+
- **`oats inspect --json` says where each layer's capability came from.**
|
|
385
|
+
Each `layers.<layer>` row gains `from`: `"soul"`, `"workspace"` (a slot
|
|
386
|
+
default or `defaults.capabilities`) or `"team:<label>"`
|
|
387
|
+
(`defaults.byTeam.<label>`). It is `null` for an empty slot. A spawn records
|
|
388
|
+
the rows in `instance.json` (`workspace.layers`), so `inspect --home`
|
|
389
|
+
reports the spawn-time origin. A home spawned earlier reports `null`.
|
|
390
|
+
Neither revision changes. Feature `layers-from`.
|
|
391
|
+
|
|
392
|
+
## Changed
|
|
393
|
+
|
|
394
|
+
- **Souls have no private mode** (human decision, 2026-09-25). `private:` in a
|
|
395
|
+
`soul.yaml` is no longer honoured: every soul of a confirmed member, and
|
|
396
|
+
every external soul, is listed (`oats souls`, `oats sync`) and spawnable, and
|
|
397
|
+
a soul row's `private` is always `false`. The field is still accepted, so
|
|
398
|
+
existing files validate (`docs/soul.schema.json` marks it deprecated), and
|
|
399
|
+
each soul that carries it gets one **`soul-private-ignored`** warning in
|
|
400
|
+
`oats sync` and `oats workspace status` (`warnings[]`: `{ code, soul,
|
|
401
|
+
repoKey, path, message }`; "`private` has no effect on a soul since 0.26.0;
|
|
402
|
+
remove it from souls/<name>/soul.yaml"). It is a warning, never a problem.
|
|
403
|
+
- **Kernel: a capability whose `compatibility.oats` the running kernel doesn't
|
|
404
|
+
satisfy is refused (`E_CAPABILITY_INCOMPATIBLE`).** This applies to package
|
|
405
|
+
and member capabilities, and to capability agents, wherever a soul resolves
|
|
406
|
+
(spawn, `spawn --preview`, `inspect --soul`, operator commands). The details
|
|
407
|
+
name the capability, the range and the kernel. Before this, the workspace
|
|
408
|
+
model never checked the range.
|
|
409
|
+
- `oats inspect` capability rows carry `compatibility: { ok, range, kernel }`.
|
|
410
|
+
- A home whose spawned module no longer admits the running kernel is not
|
|
411
|
+
refused: `inspect --home` reports a `capability-incompatible` problem.
|
|
412
|
+
|
|
413
|
+
- **Catalog: oats.authoring 1.0.3** (the bundled copy matches the tag byte for byte; the framework's `skills/integration-authoring` matches the package): the "core capabilities" wording.
|
|
414
|
+
- **Catalog: oats.jira, oats.linear and oats.dev 1.0.1** (the bundled
|
|
415
|
+
`capabilities/oats-{jira,linear,review}` copies match the tags byte for byte;
|
|
416
|
+
the framework's copy of oats.review adds only `private: true`, a member-only
|
|
417
|
+
key). Each now requires OATS >=0.26.0 and names only the workspace-model
|
|
418
|
+
homes for its settings:
|
|
419
|
+
- the soul's `tasks:` payload;
|
|
420
|
+
- `settings.<cap>` in the deployment's `oats-local.yaml`;
|
|
421
|
+
- `--provider` at spawn.
|
|
422
|
+
|
|
423
|
+
oats.dev drops its `oats-config.yaml` config template and its package
|
|
424
|
+
dependencies; oats.review is 1.2.1.
|
|
425
|
+
|
|
426
|
+
- **A soul may name several team labels** (teams contract,
|
|
427
|
+
[docs/design/2026-09-25-teams-contract.md](../design/2026-09-25-teams-contract.md)).
|
|
428
|
+
The kernel passes each label's messaging payload to the provider as
|
|
429
|
+
`OATS_TEAMS` (the eligible teams). Joining them is the messaging provider's
|
|
430
|
+
job: oats.aweb 1.14.0 joins the default personal team only, and any other
|
|
431
|
+
team on an explicit join.
|
|
432
|
+
- `soul.yaml` `team` and `oats-membership.yaml`'s `team` take a label or a
|
|
433
|
+
non-empty list of distinct labels; the first is the **primary**. A
|
|
434
|
+
one-label soul composes exactly as before (same modules, skills, injects
|
|
435
|
+
and `declRevision`); its messaging payload changes only by amendment K
|
|
436
|
+
(below).
|
|
437
|
+
- `defaults.byTeam[<label>].capabilities` applies for every label, in order.
|
|
438
|
+
Two labels that give one capability different entries are
|
|
439
|
+
`E_TEAM_CONFLICT` (naming both), unless the soul names that capability
|
|
440
|
+
itself.
|
|
441
|
+
- **The messaging provider no longer receives `byTeam[<label>]` merged into
|
|
442
|
+
its settings** (teams amendment K, co-lead ruling), the primary's included:
|
|
443
|
+
the settings are `base ⊕ soul ⊕ host ⊕ spawn`, and the per-label payloads
|
|
444
|
+
are in `OATS_TEAMS`. `OATS_TEAM_ID` (the settings' `team`) is therefore the
|
|
445
|
+
personal team a host, soul or spawn set; empty means the provider's
|
|
446
|
+
default. With oats.aweb 1.13.1 the primary identity mints into the
|
|
447
|
+
personal (root-active) team. The preview's `settingsOrigins` no longer
|
|
448
|
+
shows a `workspace-team` origin.
|
|
449
|
+
- **Revision change:** a soul whose primary label is mapped in
|
|
450
|
+
`messaging.byTeam` gets a new `payloadRevision` and `revision` (its
|
|
451
|
+
`declRevision` is unchanged), so a preview reports a payload change
|
|
452
|
+
against instances spawned before this.
|
|
453
|
+
- `OATS_TEAM_LABEL` stays the primary label. New: `OATS_TEAM_LABELS` (comma-joined), `OATS_TEAMS`
|
|
454
|
+
(`[{ label, team, mapped, payload }]`, `[]` with no label) and
|
|
455
|
+
`OATS_TEAMS_SOURCE` (`live` | `recorded`). All three are set in the
|
|
456
|
+
environment of every hook, home command and provider check, and only
|
|
457
|
+
there: a check's stdin request is unchanged, so providers that decode it
|
|
458
|
+
strictly (oats.aweb 1.13.1) keep working. They are empty when a home's
|
|
459
|
+
teams are unknown. A provider leaves a joined team only when the source is
|
|
460
|
+
`live`.
|
|
461
|
+
- A home's teams are **live** where they are acted on: the launch hook, the
|
|
462
|
+
messaging module's commands and `messaging:` operations, and `inspect
|
|
463
|
+
--home` read the workspace's current mappings in two repository reads (no
|
|
464
|
+
discovery); `readiness --home` uses the discovery it already runs. Other
|
|
465
|
+
capability commands and operations get the spawn-time list
|
|
466
|
+
(`instance.json` `teams`, `recorded`) at no remote cost. The home's modules
|
|
467
|
+
are unchanged.
|
|
468
|
+
- `oats spawn --preview` and `oats inspect` show `teams`. A label with no
|
|
469
|
+
`messaging.byTeam` entry is one `unmapped-team-label` warning, naming its
|
|
470
|
+
souls, in `oats workspace status` / `oats sync`. Feature `teams`.
|
|
471
|
+
- oats.aweb 1.13.1 ignores the new variables and keeps working.
|
|
472
|
+
|
|
473
|
+
- **Declared setting keys.** The spawn preview's `modules[]` and `oats inspect`'s
|
|
474
|
+
`capabilities[]` carry `declares`: the setting keys each manifest declares,
|
|
475
|
+
sorted, names only (`[]` when none). Feature `settings-declared`.
|
|
476
|
+
|
|
477
|
+
- **A home records its module skills.** `instance.json` `skills` lists each
|
|
478
|
+
module skill as `{ name, source: "module:<capability>" }` beside the soul's
|
|
479
|
+
own (`source: "soul"`), and `composition.materialized.skills` adds `from`:
|
|
480
|
+
the home's module copy (`.oats/modules/<capability>/…`) the skill was copied
|
|
481
|
+
from. Module skills sit under `.agents/skills/<capability>/<skill>/`.
|
|
482
|
+
- **`oats launch-config list` with only a 0.25 `oats-config.yaml` in reach**
|
|
483
|
+
answers `E_LOCAL_MISSING` naming the file instead of an empty list; inside a
|
|
484
|
+
deployment the file is `E_CONFIG_BROKEN` with `details.reason:
|
|
485
|
+
"legacy-config"`, as for every command.
|
|
486
|
+
- **Launch configurations move to `oats-local.yaml`** (lead decision 2: a
|
|
487
|
+
spawn-time host choice). The deployment's `oats-local.yaml` gains a
|
|
488
|
+
`launch-configs:` key with the same entries (`runtime`, `executable`, `args`,
|
|
489
|
+
`env`, `model`, `yolo`); `oats launch-config set | remove` rewrite only that
|
|
490
|
+
block, and `list` / `preview`, `--launch-config` on `oats spawn` and on
|
|
491
|
+
`oats session start | restart`, and the `launch-config` feature are unchanged.
|
|
492
|
+
There is one host file and no scope chain: `list` rows keep `source` (the
|
|
493
|
+
deployment directory) and an always-empty `shadows`. A relative `executable`
|
|
494
|
+
resolves against the deployment directory. A home's launch configurations
|
|
495
|
+
are its deployment's, found walking up from the home.
|
|
496
|
+
- **Upgrading:** a scope's `oats-config.yaml` that still declares
|
|
497
|
+
`launch-configs:` is refused (its readers, and the `launch-config`
|
|
498
|
+
commands, name the move). Move the block into `oats-local.yaml`, or
|
|
499
|
+
re-declare each entry with `oats launch-config set <name> --file <json>`
|
|
500
|
+
from the deployment. `set` with no `oats-local.yaml` in reach is
|
|
501
|
+
`E_LOCAL_MISSING`.
|
|
502
|
+
- **The capability manifest contract is checked where a workspace reads the
|
|
503
|
+
manifest.** The rules the kernel enforced only on classic capabilities now
|
|
504
|
+
apply to member and package capabilities too, before anything runs:
|
|
505
|
+
- a launch `environment` name inside the capability's vendor namespace (or an
|
|
506
|
+
`environmentNamespaces` prefix that is not reserved), never a core or
|
|
507
|
+
process bootstrap variable;
|
|
508
|
+
- hooks: an approved event, a command string or `{ command, required,
|
|
509
|
+
inputs }`, `required: true` only on the spawn hook, and a script path inside
|
|
510
|
+
the capability directory;
|
|
511
|
+
- hooks and launch environment only on a dotted id (`acme.tool`): an
|
|
512
|
+
undotted id has no vendor namespace to claim.
|
|
513
|
+
|
|
514
|
+
A member capability that breaks one is a discovery problem
|
|
515
|
+
(`E_WORKSPACE_SCHEMA` at `capabilities/<dir>/oats.json#<pointer>`, shown by
|
|
516
|
+
`oats workspace status`) and is not listed; a soul that declares it is
|
|
517
|
+
refused with that problem (`reason: "manifest-contract"`), not "missing". A
|
|
518
|
+
package capability that breaks one is `E_PACKAGE_MANIFEST` at `oats sync`.
|
|
519
|
+
- **A provider payload value outside the manifest's `settings.<key>.values`
|
|
520
|
+
is refused** (`E_WORKSPACE_SCHEMA`, `reason: "setting-value"`, naming where
|
|
521
|
+
it was set: a `--provider` flag, `oats-local.yaml` settings, the soul or the
|
|
522
|
+
workspace). A misspelled value used to be recorded and skip every
|
|
523
|
+
conditional `requires` row that reads it.
|
|
524
|
+
- **A capability agent is a workspace-model spawn of its providing module
|
|
525
|
+
only** (lead decision c3 Q1). `oats spawn <agent>` for a capability's
|
|
526
|
+
`agents:` soul (OKF's `memory-harvest`, `oats.review`'s `reviewer`) records
|
|
527
|
+
`modules`/`providers`/`workspace` like any v2 home, and composes exactly one
|
|
528
|
+
module: the capability that declares the agent. The module comes from the
|
|
529
|
+
`--parent`/`--relative-to` instance's verified copy (pinned to its recorded
|
|
530
|
+
digest, with its recorded payload), else from a home that carries it, else
|
|
531
|
+
from a confirmed member capability or a locked package that declares the
|
|
532
|
+
agent (the source instance may be gone). A capability agent gets no
|
|
533
|
+
knowledge, messaging or tasks module and runs no provider hook, its providing
|
|
534
|
+
module's included: a harvester never registers as a knowledge source or gets
|
|
535
|
+
a messaging identity. A knowledge-layer provider's inject is left out.
|
|
536
|
+
- **`instance.json` records `workspace.name` and `workspace.deployment`**
|
|
537
|
+
(M5/3a). `oats inspect --home` reports the recorded workspace name without
|
|
538
|
+
discovery, and `oats operation run --home` hands it to the provider as
|
|
539
|
+
`OATS_WORKSPACE_NAME`. Homes spawned before 0.26.0 have neither.
|
|
540
|
+
|
|
541
|
+
- **`oats inspect`, `oats readiness` and `oats operation run` read the
|
|
542
|
+
workspace model** on a workspace deployment and for every home whose
|
|
543
|
+
`instance.json` records `modules`. They never read the classic config chain.
|
|
544
|
+
The probe integers are the gate: `operationsApi: 2`, `soulsApi: 2` (the
|
|
545
|
+
inspect soul rows) and `readinessApi: 2`. `oats souls --json` keeps
|
|
546
|
+
`soulsApi: 1`, since its shape is unchanged. Shapes and examples are in
|
|
547
|
+
[desktop-cli-api.md](../desktop-cli-api.md#inspect-readiness-and-operation-run-on-the-workspace-model-operationsapi-2-soulsapi-2-readinessapi-2-oats-0260).
|
|
548
|
+
- The subject is an instance (`--home`: `{kind:"instance", instance, home,
|
|
549
|
+
soul}`) or a soul (`--soul`: `{kind:"soul", soul, repoKey, commit,
|
|
550
|
+
team}`). A workspace deployment with neither is `E_BAD_ARGS`; the
|
|
551
|
+
scope-wide lists are `oats souls` and `oats capabilities`.
|
|
552
|
+
- Payloads lose `scope` (`chain`, `team`, `agentsRoots`), config `levels`,
|
|
553
|
+
`activation`, `currentConfig`, `snapshot`, `health.trusted` and the
|
|
554
|
+
portable `sources`. A capability's origin is its module's `from`; its
|
|
555
|
+
settings are the merged provider payload.
|
|
556
|
+
- Readiness checks are `installed | configured | member | providers`:
|
|
557
|
+
- `trusted` is removed, and `--verify-signatures` is `E_BAD_ARGS`.
|
|
558
|
+
- `enrolled` is now `member`: the soul's member repository confirmed in
|
|
559
|
+
the workspace (`oats-membership.yaml`), never `oats.yaml`.
|
|
560
|
+
- `providers` is new: each bound provider's own binding check, relayed
|
|
561
|
+
verbatim as `{status, problems, warnings}`. The status maps to the item:
|
|
562
|
+
- `ready` → pass;
|
|
563
|
+
- `needs-configuration` or `authorization-required` → fail;
|
|
564
|
+
- `unavailable` → unknown.
|
|
565
|
+
|
|
566
|
+
`warnings` is optional in the provider's answer and always present in
|
|
567
|
+
the relay (`[]` when absent). It never changes the status: a ready
|
|
568
|
+
binding with a warning still passes. The answer is decoded by the
|
|
569
|
+
binding wire's rules (exit 0, one strict JSON document, the envelope
|
|
570
|
+
echo, no problems on `ready`); anything else is `unknown`. All provider
|
|
571
|
+
checks share one 60 s budget per read. Provider authors: the request,
|
|
572
|
+
environment and answer are specified in
|
|
573
|
+
[capabilities.md](../capabilities.md#readiness-check-bindingcheck).
|
|
574
|
+
- A soul whose packages the lock does not provide fails `installed` with
|
|
575
|
+
the typed code and an `oats sync` remedy.
|
|
576
|
+
- The probe's integers say the kernel can answer the v2 shapes. Dispatch
|
|
577
|
+
on each payload's own integer; the v1 shapes are removed (see Removed).
|
|
578
|
+
- The `readiness-verify` feature is no longer advertised.
|
|
579
|
+
- A v2 home's deployment is derived from its path
|
|
580
|
+
(`<deployment>/agents/<soul>/instances/<name>`), and
|
|
581
|
+
`<deployment>/oats-local.yaml` must exist exactly there (`E_HOME_MISMATCH`
|
|
582
|
+
otherwise). A v2 spawn ignores an ambient `PI_AGENTS_ROOT` / `OATS_ROOT`.
|
|
583
|
+
- A module tree in the deployment's store (used by readiness `--soul`,
|
|
584
|
+
`operation run --soul` and `oats <ns>` dispatch) runs only while it
|
|
585
|
+
matches the digest verified when it was fetched at the locked commit. A
|
|
586
|
+
drifted tree is fetched again; a fetch that does not verify is
|
|
587
|
+
`E_PACKAGE_INTEGRITY`.
|
|
588
|
+
- `readiness --policy` is kept, with the same shape. The selector echo moves
|
|
589
|
+
from `subject.selector` to a top-level `selector`.
|
|
590
|
+
- `oats operation run` runs the module that fills the layer for the home or
|
|
591
|
+
the soul. There is no trust gate, and the result carries
|
|
592
|
+
`operationsApi: 2`. Remote routing accepts a destination advertising
|
|
593
|
+
`operationsApi` 1 or 2.
|
|
594
|
+
|
|
595
|
+
- **Manifest setting defaults reach workspace spawns** (addendum 5). A
|
|
596
|
+
capability's declared `settings.<key>.default` (for example oats.aweb's
|
|
597
|
+
`identity: { mode: local }`) is now the lowest layer of the merged provider
|
|
598
|
+
payload on `oats spawn`, `--preview` and `oats inspect --soul`, below the
|
|
599
|
+
workspace, team, soul, host and `--provider` layers. The provider receives it
|
|
600
|
+
in `OATS_SETTINGS` and `instance.json` `providers.<cap>` records it. The
|
|
601
|
+
preview's new `settingsOrigins.<cap>` says where each leaf came from
|
|
602
|
+
(`manifest-default`, `workspace`, `workspace-team`, `soul`, `host`,
|
|
603
|
+
`spawn`; feature `settings-origins`), so a Desktop shows "Default" without
|
|
604
|
+
hardcoding it. The decision
|
|
605
|
+
binds the payload by value, defaults included. An instance spawned before
|
|
606
|
+
0.26.0 keeps the payload it recorded, without the defaults.
|
|
607
|
+
|
|
608
|
+
## Fixed
|
|
609
|
+
|
|
610
|
+
- **Every team label's messaging payload is validated.** A soul with several
|
|
611
|
+
labels had only its primary label's `messaging.byTeam` entry checked, though
|
|
612
|
+
every label's entry reaches the provider in `OATS_TEAMS`. A secondary
|
|
613
|
+
label's entry could carry a manifest `hostOnly` key or a nested `byTeam`
|
|
614
|
+
unchecked. Each label the soul carries is now refused the same way, with
|
|
615
|
+
`E_WORKSPACE_SCHEMA` (reason `host-only-key` or `reserved-key`) and the
|
|
616
|
+
path `/messaging/byTeam/<label>/…`.
|
|
617
|
+
- **Team facts in a home's launch and retire hooks.** A home's `launch` and
|
|
618
|
+
`retire` hooks received an empty `OATS_TEAM_LABEL` and `OATS_TEAM_ID`. The
|
|
619
|
+
kernel read the recorded workspace in the wrong shape, while spawn hooks and
|
|
620
|
+
home commands got the right values. They now get the soul's primary label and
|
|
621
|
+
the recorded messaging payload's team id.
|
|
622
|
+
- **Session start and restart of a workspace-model home.** Every start or
|
|
623
|
+
restart of a home that records `modules` and a launch recipe refused with
|
|
624
|
+
`E_LAUNCH_PREPARATION` ("… is no longer installed in the scope"): the
|
|
625
|
+
launch providers' manifests were looked up from the home's recorded work
|
|
626
|
+
repository instead of the home's own module copies. A module home now reads
|
|
627
|
+
them from `<home>/.oats/modules`, and is never re-resolved against the scope;
|
|
628
|
+
a module copy that is missing is its own refusal naming the directory.
|
|
629
|
+
|
|
630
|
+
- **A spawn preview writes nothing, the first one included.** The first
|
|
631
|
+
`oats spawn <soul> --preview` of a workspace soul (or of a new member commit)
|
|
632
|
+
used to fill the deployment's soul cache (`agents/<soul>/souls/<commit>/`)
|
|
633
|
+
and move the `agents/<soul>/soul` pointer. A preview now reads the cache when
|
|
634
|
+
a spawn already filled it, else fetches the soul to a temporary copy outside
|
|
635
|
+
the deployment and removes it; `soulFetched: true` still says it fetched. The
|
|
636
|
+
deployment is byte-identical after any preview, as `spawnPreviewApi 2`
|
|
637
|
+
promises (docs/desktop-cli-api.md).
|
|
638
|
+
|
|
639
|
+
- **`oats retire <unknown>` is a typed refusal.** An instance name with no home
|
|
640
|
+
under the agents root used to escape as an untyped error with a stack trace
|
|
641
|
+
(no `--json` envelope). It is now `E_SESSION_UNKNOWN` (`no instance named
|
|
642
|
+
"<name>"`), the code every lookup by instance name answers, exit 1, one
|
|
643
|
+
envelope under `--json`.
|
|
644
|
+
|
|
645
|
+
- **Instance names are unique across the deployment.** A derived name used to
|
|
646
|
+
de-duplicate only within its own soul's `instances/`, so soul `a` with
|
|
647
|
+
`--purpose b-c` and soul `a-b` with `--purpose c` both got `a-b-c`. Derived
|
|
648
|
+
names now skip every instance and soul name in the deployment (`-2`, `-3`, …).
|
|
649
|
+
|
|
650
|
+
- **`oats status` shows a workspace soul as it is written.** A soul row read a
|
|
651
|
+
`schemaVersion: 2` soul.yaml with the classic flat reader: a nested map
|
|
652
|
+
(`capabilities`, `knowledge` …) came out as `""` and `schemaVersion` as the
|
|
653
|
+
string `"2"`. Such a soul.yaml is now read with the YAML parser: the row
|
|
654
|
+
carries the maps as maps, `schemaVersion: 2` and booleans as booleans.
|
|
655
|
+
|
|
656
|
+
- **`oats doctor --soul <name>` includes module injects.** On a workspace
|
|
657
|
+
deployment it composed through the classic config chain, so the capability
|
|
658
|
+
injects a spawned home carries were missing. It now resolves the soul over
|
|
659
|
+
the workspace remotes as a spawn preview does and composes the full text
|
|
660
|
+
(module inject blocks are named home-relative, `.oats/modules/<cap>/…`). It
|
|
661
|
+
writes nothing in the deployment; an unknown soul is `E_SOUL_UNKNOWN`.
|
|
662
|
+
Without `--soul`, doctor stays offline.
|
|
663
|
+
|
|
664
|
+
- **Capability commands recognise `OATS_INSTANCE_HOME`.** Dispatch found the
|
|
665
|
+
instance home only from `PI_AGENT_HOME` / `OATS_HOME`; the canonical
|
|
666
|
+
`OATS_INSTANCE_HOME` now counts, and wins when several are set.
|
|
667
|
+
|
|
668
|
+
- **Launch-preparation refusals name no removed verb.** The classic
|
|
669
|
+
`E_LAUNCH_PREPARATION` remedies said "reinstall it (oats install)" and
|
|
670
|
+
"re-trust it (oats trust)"; the remedy is now "respawn the instance".
|