@awebai/oats 0.36.0 → 0.36.1
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/bin/oats.mjs +21 -4
- package/docs/configuration.md +6 -0
- package/docs/desktop-cli-api.md +37 -8
- package/docs/integrations.md +1 -1
- package/docs/knowledge.md +1 -1
- package/docs/oats-workspace.schema.json +28 -0
- package/docs/official-catalog.md +3 -3
- package/docs/packages.md +12 -12
- package/docs/release-notes/v0.36.1.md +103 -0
- package/docs/souls-and-instances.md +2 -2
- package/docs/workspaces.md +35 -2
- package/lib/teams.mjs +36 -3
- package/lib/workspace.mjs +14 -0
- package/package-catalog.json +2 -2
- package/package.json +1 -1
- package/skills/oats-getting-started/SKILL.md +2 -2
package/bin/oats.mjs
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
writeFileAtomic, LOCK_FILE, readLock, readLockIfPresent, writeLock, resolvePackages, memoizedRemote,
|
|
37
37
|
classifyPackageValue, parsePackageRequest } from "../lib/packages.mjs";
|
|
38
38
|
import { loadLocal, validateWorkspace, validateLocal, discoverPackageSouls, workspaceWarnings, memberRowByKey } from "../lib/workspace.mjs";
|
|
39
|
-
import { recordedTeams, reportRows, soulKeyOf, soulTeams, teamModel } from "../lib/teams.mjs";
|
|
39
|
+
import { migrationProblems, recordedTeams, reportRows, soulKeyOf, soulTeams, teamModel } from "../lib/teams.mjs";
|
|
40
40
|
import { launchLayers } from "../lib/launch-preference.mjs";
|
|
41
41
|
import { parseConfigData } from "../lib/config-data.mjs";
|
|
42
42
|
import * as remoteModule from "../lib/remote.mjs";
|
|
@@ -221,6 +221,19 @@ async function doctorComposition(ctx, soulName, ws, bail) {
|
|
|
221
221
|
} finally { for (const c of cleanups) { try { c(); } catch { /* best effort: temporary copies only */ } } }
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
/** team-model-3-migration in doctor (0.36.x), OFFLINE like the rest of doctor: oats-local.yaml, and for its
|
|
225
|
+
* local teams the workspace file this machine's parsed cache holds (cachedWorkspace: no git process, no
|
|
226
|
+
* network). Without that file, whether local teams need `localTeams: true` is said to be unchecked
|
|
227
|
+
* (information), never guessed. The standalone view has no workspace rules. → { problems, information } */
|
|
228
|
+
function doctorTeamMigration(local) {
|
|
229
|
+
const standalone = typeof local.standalone === "string" && local.standalone !== "";
|
|
230
|
+
const file = standalone ? null : cachedWorkspace(local.workspace)?.file ?? null;
|
|
231
|
+
const model = teamModel(file, local);
|
|
232
|
+
const unchecked = !standalone && file === null && model.migration.teamKeys.length > 0;
|
|
233
|
+
return { problems: migrationProblems(model),
|
|
234
|
+
information: unchecked ? ["team-model-3-migration: whether oats-local.yaml teams/defaultTeam need localTeams: true couldn't be checked: this deployment hasn't observed its workspace yet; run oats sync"] : [] };
|
|
235
|
+
}
|
|
236
|
+
|
|
224
237
|
/** Workspace-model v2 doctor data, OFFLINE: the deployment declaration found
|
|
225
238
|
* walking up from ctx (oats-local.yaml) and the lock v3 beside it. Doctor never
|
|
226
239
|
* goes to the network for this view (only `--soul`, which resolves the soul like a
|
|
@@ -230,7 +243,7 @@ function doctorLockData(ctx) {
|
|
|
230
243
|
let lockDir = ctx;
|
|
231
244
|
try {
|
|
232
245
|
const found = loadLocal(ctx);
|
|
233
|
-
out.local = { path: found.path, workspace: found.local.workspace };
|
|
246
|
+
out.local = { path: found.path, workspace: found.local.workspace, value: found.local };
|
|
234
247
|
lockDir = dirname(found.path);
|
|
235
248
|
} catch (e) {
|
|
236
249
|
// An unreadable oats-local.yaml, or a 0.25 oats-config.yaml inside the deployment
|
|
@@ -584,12 +597,13 @@ function legacyLayoutProblems(root) {
|
|
|
584
597
|
async function doctorWorkspaceJson(ctx, soulName, ws) {
|
|
585
598
|
const composition = await doctorComposition(ctx, soulName, ws, (code, msg, details) => jsonFail(code, msg, details));
|
|
586
599
|
const agentsRoot = join(dirname(ws.local.path), "agents");
|
|
587
|
-
const
|
|
600
|
+
const migration = doctorTeamMigration(ws.local.value);
|
|
601
|
+
const problems = [...legacyLayoutProblems(agentsRoot), readableInstanceHomes(agentsRoot), ...migration.problems].filter(Boolean);
|
|
588
602
|
return {
|
|
589
603
|
schemaVersion: 1, workspaceApi: 2, context: ctx,
|
|
590
604
|
workspace: { file: ws.local.path, ref: ws.local.workspace },
|
|
591
605
|
workspaceError: ws.localError, lockFile: ws.lockFile, packages: ws.packages, lockError: ws.lockError,
|
|
592
|
-
information: operationalKnowledgeNote(composition, soulName) ? [operationalKnowledgeNote(composition, soulName)] : [],
|
|
606
|
+
information: [...(operationalKnowledgeNote(composition, soulName) ? [operationalKnowledgeNote(composition, soulName)] : []), ...migration.information],
|
|
593
607
|
composedInstructions: composition?.text, instructionBlocks: composition?.blocks,
|
|
594
608
|
...(problems.length ? { problems } : {}),
|
|
595
609
|
};
|
|
@@ -624,7 +638,10 @@ async function doctor(dir) {
|
|
|
624
638
|
const composition = await doctorComposition(ctx, soulName, ws, (code, msg) => die(`${msg} [${code}]`));
|
|
625
639
|
printDoctorWorkspace(ws);
|
|
626
640
|
const agentsRoot = join(dirname(ws.local.path), "agents");
|
|
641
|
+
const migration = doctorTeamMigration(ws.local.value);
|
|
627
642
|
for (const p of [...legacyLayoutProblems(agentsRoot), readableInstanceHomes(agentsRoot)].filter(Boolean)) console.log(`\n! ${p.code}: ${p.message}`);
|
|
643
|
+
for (const p of migration.problems) console.log(`\n! ${p.code}: ${p.message} — ${p.fix}`);
|
|
644
|
+
for (const line of migration.information) console.log(`\nINFO: ${line}`);
|
|
628
645
|
if (soulName) {
|
|
629
646
|
const information = operationalKnowledgeNote(composition, soulName);
|
|
630
647
|
if (information) console.log(`\nINFO: ${information}`);
|
package/docs/configuration.md
CHANGED
|
@@ -81,6 +81,12 @@ refused (`E_WORKSPACE_SCHEMA`).
|
|
|
81
81
|
How teams are resolved, and what a messaging provider does with them, is in
|
|
82
82
|
[workspaces.md](workspaces.md#teams).
|
|
83
83
|
|
|
84
|
+
OATS 0.37.0 (team model 3) removes `souls.teams` and `souls.default` (they move
|
|
85
|
+
to `souls:` in `oats-workspace.yaml`) and allows `teams` and `defaultTeam` here
|
|
86
|
+
only when the workspace file says `localTeams: true`. 0.36.x still applies all
|
|
87
|
+
four keys and warns about them (`team-model-3-migration`): see
|
|
88
|
+
[Preparing for team model 3](workspaces.md#preparing-for-team-model-3-036x).
|
|
89
|
+
|
|
84
90
|
## Launch configurations
|
|
85
91
|
|
|
86
92
|
An entry has `harness` (`pi` \| `claude` \| `codex`, required), `executable`
|
package/docs/desktop-cli-api.md
CHANGED
|
@@ -725,7 +725,7 @@ Read-only (it writes no lock):
|
|
|
725
725
|
"souls":["rm"],"capabilities":["nw-house-style"],"publishes":null,"url":"https://github.com/nw/agents/tree/66566512…",
|
|
726
726
|
"membershipFile":{"path":"oats-membership.yaml","url":"https://github.com/nw/agents/blob/66566512…/oats-membership.yaml"}}],
|
|
727
727
|
"packages":[{"id":"oats.okf","version":"3.0.0","source":"catalog:oats.okf","commit":"ab897841…","integrity":"sha256-bada35…",
|
|
728
|
-
"capabilities":["oats.okf"],"souls":[],"latest":{"version":"4.1.
|
|
728
|
+
"capabilities":["oats.okf"],"souls":[],"latest":{"version":"4.1.1","ref":"v4.1.1"}}],
|
|
729
729
|
"declaredPackages":["oats.framework","oats.okf"],"unsynced":["oats.framework"],"stale":[],
|
|
730
730
|
"external":[{"source":"git:github.com/oss/experts@3c606e09…","soul":"security-reviewer"}],
|
|
731
731
|
"problems":[],"warnings":[],
|
|
@@ -784,8 +784,8 @@ packages' capabilities and souls, sorted by name, then origin. Both carry
|
|
|
784
784
|
"defaultTeam":{"label":"mine","team":"mine:ana.aweb.ai","from":"deployment"},
|
|
785
785
|
"private":false,"path":"souls/writer","work":"directory","description":"Drafts campaigns.","harness":"pi","model":null,"harnessFrom":"kernel-default",
|
|
786
786
|
"file":{"path":"souls/writer/soul.yaml","url":null},"spawnable":true,"problem":null},
|
|
787
|
-
{"name":"knowledge-maintainer","qualifiedName":"oats.okf/knowledge-maintainer","origin":"package oats.okf v4.1.
|
|
788
|
-
"version":"4.1.
|
|
787
|
+
{"name":"knowledge-maintainer","qualifiedName":"oats.okf/knowledge-maintainer","origin":"package oats.okf v4.1.1","kind":"package","package":"oats.okf",
|
|
788
|
+
"version":"4.1.1","repoKey":"github.com/awebai/oats-okf","commit":"e1d604f7…","teams":null,"defaultTeam":null,"private":false,
|
|
789
789
|
"path":"oats-package/souls/knowledge-maintainer","work":"directory","description":"Reviews harvested knowledge.","harness":"pi","model":null,
|
|
790
790
|
"harnessFrom":"kernel-default","file":{"path":"oats-package/souls/knowledge-maintainer/soul.yaml","url":null},
|
|
791
791
|
"spawnable":false,"problem":{"code":"E_TEAM_UNKNOWN","message":"team \"reviewers\" is not declared (oats-local.yaml#/souls/teams/…)"}}],
|
|
@@ -874,8 +874,8 @@ nothing reads a working clone.
|
|
|
874
874
|
**The show:**
|
|
875
875
|
|
|
876
876
|
```json
|
|
877
|
-
{"capabilityShowApi":1,"name":"oats.okf","kind":"package","repoKey":"github.com/awebai/oats-okf","package":"oats.okf","version":"4.1.
|
|
878
|
-
"commit":"
|
|
877
|
+
{"capabilityShowApi":1,"name":"oats.okf","kind":"package","repoKey":"github.com/awebai/oats-okf","package":"oats.okf","version":"4.1.1",
|
|
878
|
+
"commit":"e1d604f7…","path":"oats-package/capabilities/oats-okf",
|
|
879
879
|
"inject":{"path":"injects/okf.md","bytes":2422,"text":"## Knowledge: OKF\n\nYou have two kinds of knowledge. …","binary":false,"truncated":false},
|
|
880
880
|
"skills":[{"name":"okf-consultation","path":"skills/okf-consultation","description":"Consulting your soul's knowledge with the `oats okf` CLI: …",
|
|
881
881
|
"files":[{"path":"skills/okf-consultation/SKILL.md","bytes":6947},{"path":"skills/okf-consultation/references/consult.md","bytes":4465}],
|
|
@@ -901,7 +901,7 @@ nothing reads a working clone.
|
|
|
901
901
|
**The `--file` answer:**
|
|
902
902
|
|
|
903
903
|
```json
|
|
904
|
-
{"capabilityShowApi":1,"name":"oats.okf","kind":"package","commit":"
|
|
904
|
+
{"capabilityShowApi":1,"name":"oats.okf","kind":"package","commit":"e1d604f7…",
|
|
905
905
|
"file":{"path":"skills/okf-instance-knowledge/SKILL.md","bytes":4787,"text":"---\nname: okf-instance-knowledge\n…","binary":false,"truncated":false}}
|
|
906
906
|
```
|
|
907
907
|
|
|
@@ -1229,9 +1229,38 @@ for a failure and `false` for a warning, plus the problem's own keys.
|
|
|
1229
1229
|
| `default-team-changed` | warning | `recorded`, `current` | `--home` with live teams: the default changed since the spawn |
|
|
1230
1230
|
| `E_TEAM_UNKNOWN` | failure | `label`, `at` | a reference to an undeclared label |
|
|
1231
1231
|
| `E_TEAM_NOT_ELIGIBLE` | failure | `soul`, `label`, `at` | `souls.default` outside the soul's teams |
|
|
1232
|
+
| `team-model-3-migration` | warning | `condition`, `keys` | 0.36.x: what OATS 0.37.0 (team model 3) refuses, one item per condition (below) |
|
|
1232
1233
|
|
|
1233
|
-
The
|
|
1234
|
-
details.
|
|
1234
|
+
The `E_TEAM_UNKNOWN` and `E_TEAM_NOT_ELIGIBLE` codes are also spawn, preview and
|
|
1235
|
+
inspect refusals, with the same details.
|
|
1236
|
+
|
|
1237
|
+
`team-model-3-migration` is a deployment fact, so every soul's readiness
|
|
1238
|
+
carries it, and `oats teams` lists it once. Its `condition`:
|
|
1239
|
+
|
|
1240
|
+
- `local-soul-teams`: `oats-local.yaml` has `souls.teams` and/or
|
|
1241
|
+
`souls.default` (`keys`: `["souls.teams", "souls.default"]` as found). They
|
|
1242
|
+
move to `souls:` in `oats-workspace.yaml`.
|
|
1243
|
+
- `local-teams-closed`: `oats-local.yaml` declares `teams` and/or
|
|
1244
|
+
`defaultTeam` (`keys`: `["teams", "defaultTeam"]` as found) and the
|
|
1245
|
+
workspace file does not say `localTeams: true`. The `fix` names both
|
|
1246
|
+
remedies: add `localTeams: true` to the workspace file, or commit the teams
|
|
1247
|
+
and `defaultTeam` there and remove them locally. Never raised in the
|
|
1248
|
+
standalone view, which has no workspace rules.
|
|
1249
|
+
|
|
1250
|
+
```json
|
|
1251
|
+
{"code":"team-model-3-migration","severity":"warning","condition":"local-teams-closed","keys":["teams","defaultTeam"],
|
|
1252
|
+
"message":"oats-local.yaml declares teams, defaultTeam, but oats-workspace.yaml does not say localTeams: true: OATS 0.37.0 refuses local teams and a local defaultTeam unless the workspace allows them",
|
|
1253
|
+
"fix":"either (a) add `localTeams: true` to oats-workspace.yaml, or (b) commit the teams and defaultTeam in oats-workspace.yaml, then remove them from oats-local.yaml"}
|
|
1254
|
+
```
|
|
1255
|
+
|
|
1256
|
+
As a readiness item it is `{subject: "teams", status: "fail", required: false,
|
|
1257
|
+
producer: "team model", code, reason: <message>, remedy: <fix>, condition,
|
|
1258
|
+
keys}`. `oats doctor --json` lists the same problems under `problems[]`. Doctor
|
|
1259
|
+
stays offline: for `local-teams-closed` it reads only the workspace file this
|
|
1260
|
+
machine's parsed cache holds; when there is none, it adds no problem and says
|
|
1261
|
+
so in `information[]`: `"team-model-3-migration: whether oats-local.yaml
|
|
1262
|
+
teams/defaultTeam need localTeams: true couldn't be checked: this deployment
|
|
1263
|
+
hasn't observed its workspace yet; run oats sync"`.
|
|
1235
1264
|
|
|
1236
1265
|
<a id="soul-launch-preferences-feature-launch-preference-oats-0300"></a>
|
|
1237
1266
|
## Launch preferences
|
package/docs/integrations.md
CHANGED
package/docs/knowledge.md
CHANGED
|
@@ -27,6 +27,20 @@
|
|
|
27
27
|
"additionalProperties": { "$ref": "#/$defs/team" },
|
|
28
28
|
"description": "SHARED teams: <label>: { description?, team? }. `team` is the messaging provider's team id, the same for everyone; without it the team is declared but not yet created (readiness team-unmapped). Local teams, the default and which teams each soul belongs to live in the deployment's oats-local.yaml (`oats teams`, `oats soul teams`). A label never gates, restricts or partitions anything."
|
|
29
29
|
},
|
|
30
|
+
"defaultTeam": {
|
|
31
|
+
"$ref": "#/$defs/label",
|
|
32
|
+
"description": "Team model 3 (0.37.0): the workspace's fallback default team, a label of teams: in this file. 0.36.x accepts and validates it without applying it."
|
|
33
|
+
},
|
|
34
|
+
"localTeams": {
|
|
35
|
+
"type": "boolean",
|
|
36
|
+
"description": "Team model 3 (0.37.0): whether deployments may declare their own teams and defaultTeam in oats-local.yaml. Absent: false. 0.36.x accepts it without applying it."
|
|
37
|
+
},
|
|
38
|
+
"souls": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"propertyNames": { "type": "string", "pattern": "^(?:\\*|[a-z0-9][a-z0-9._-]*/(?:\\*|[a-z0-9]+(?:-[a-z0-9]+)*))$" },
|
|
41
|
+
"additionalProperties": { "$ref": "#/$defs/soulTeams" },
|
|
42
|
+
"description": "Team model 3 (0.37.0): per soul pattern (\"*\", <member|package>/* or <member|package>/<soul>; the most specific key wins outright), the soul's default team and the other teams it may join. Every label is a label of teams: in this file. 0.36.x accepts and validates it without applying it."
|
|
43
|
+
},
|
|
30
44
|
"defaults": { "$ref": "#/$defs/defaults" },
|
|
31
45
|
"stores": {
|
|
32
46
|
"type": "object",
|
|
@@ -111,6 +125,20 @@
|
|
|
111
125
|
"team": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@/+-]{0,255}$", "description": "The messaging provider's team id (for oats.aweb, <team>:<namespace>). Absent: declared, not yet created. The kernel's safety rule: never '-'-led, no whitespace or control characters, at most 256 characters; the provider validates its own shape." }
|
|
112
126
|
}
|
|
113
127
|
},
|
|
128
|
+
"soulTeams": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"additionalProperties": false,
|
|
131
|
+
"properties": {
|
|
132
|
+
"default": { "$ref": "#/$defs/label", "description": "The soul's default team: a label of teams: in this file." },
|
|
133
|
+
"teams": {
|
|
134
|
+
"anyOf": [
|
|
135
|
+
{ "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/label" } },
|
|
136
|
+
{ "const": "any" }
|
|
137
|
+
],
|
|
138
|
+
"description": "The other teams the soul may join: labels of teams: in this file, or \"any\" for every one. [] (or no teams) is default only."
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
},
|
|
114
142
|
"defaults": {
|
|
115
143
|
"type": "object",
|
|
116
144
|
"additionalProperties": false,
|
package/docs/official-catalog.md
CHANGED
|
@@ -9,8 +9,8 @@ or workspace membership alone does not make a package official.
|
|
|
9
9
|
|
|
10
10
|
| package | release | capabilities | package souls |
|
|
11
11
|
|---|---|---|---|
|
|
12
|
-
| `oats.framework` | `oats-framework/v1.4.
|
|
13
|
-
| `oats.okf` | `v4.1.
|
|
12
|
+
| `oats.framework` | `oats-framework/v1.4.2` (this repository) | `oats.core`, `oats.setup`, `oats.knowledge-theory` | `knowledge-theory-expert` |
|
|
13
|
+
| `oats.okf` | `v4.1.1` | `oats.okf` (knowledge), `oats.okf-harvest`, `oats.okf-maintenance` | `knowledge-harvester`, `knowledge-maintainer` |
|
|
14
14
|
| `oats.aweb` | `v1.17.7` | `oats.aweb` (messaging) | |
|
|
15
15
|
| `oats.engineering` | `v1.5.0` | `oats.engineering-expert`, `oats.developer`, `oats.code-review` | `code-reviewer` |
|
|
16
16
|
| `oats.authoring` | `v1.0.3` | `oats.authoring` | |
|
|
@@ -27,7 +27,7 @@ no lock and adds nothing to an existing workspace.
|
|
|
27
27
|
## Find and use packages
|
|
28
28
|
|
|
29
29
|
- A workspace pins an official package by **bare version** in its
|
|
30
|
-
`packages:` map (`oats.okf: v4.1.
|
|
30
|
+
`packages:` map (`oats.okf: v4.1.1`); `oats sync` resolves it through the
|
|
31
31
|
catalog to an exact commit, fetches it, verifies its integrity and locks it.
|
|
32
32
|
A package outside the catalog is written `git:<repo>@<ref>`. Pinning does
|
|
33
33
|
not join a team or adopt the publisher's workspace. See
|
package/docs/packages.md
CHANGED
|
@@ -44,14 +44,14 @@ whole organisation:
|
|
|
44
44
|
|
|
45
45
|
```yaml
|
|
46
46
|
packages:
|
|
47
|
-
oats.okf: v4.1.
|
|
47
|
+
oats.okf: v4.1.1 # bare version → the official catalog
|
|
48
48
|
acme.tools: git:github.com/acme/tools@v0.4.0 # direct ref: git:<repo>@<tag or full OID>
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
- **Bare version** (`v4.1.
|
|
51
|
+
- **Bare version** (`v4.1.1`, `4.1.1`, `1.0.0-rc.1`): the id is looked up in
|
|
52
52
|
the official catalog — `package-catalog.json` in the `oats` repo, or the file
|
|
53
53
|
named by `OATS_PACKAGE_CATALOG` — which supplies the repo url, the tag
|
|
54
|
-
convention (`v4.1.
|
|
54
|
+
convention (`v4.1.1` or `oats-framework/v1.4.2`) and the payload path. An id
|
|
55
55
|
the catalog does not know is `E_PACKAGE_MISSING` ("use `git:<repo>@<ref>` for
|
|
56
56
|
a package outside the catalog"). The catalog is the reviewed official list
|
|
57
57
|
([official-catalog.md](official-catalog.md)) and the only way a
|
|
@@ -74,8 +74,8 @@ members:
|
|
|
74
74
|
- git:github.com/acme/agents
|
|
75
75
|
- git:github.com/acme/platform
|
|
76
76
|
packages:
|
|
77
|
-
oats.framework: v1.4.
|
|
78
|
-
oats.okf: v4.1.
|
|
77
|
+
oats.framework: v1.4.2
|
|
78
|
+
oats.okf: v4.1.1
|
|
79
79
|
oats.aweb: v1.17.7
|
|
80
80
|
teams:
|
|
81
81
|
platform: { team: "platform:acme.aweb.ai", description: Platform engineering }
|
|
@@ -105,7 +105,7 @@ decision recorded in the lock.
|
|
|
105
105
|
$ oats sync
|
|
106
106
|
workspace acme (github.com/acme/agents @ 3f2a9c1e)
|
|
107
107
|
members agents ✓↔ (@ 3f2a9c1e) platform ✓↔ (@ 77c0a1b2) billing ✗ (no-backlink)
|
|
108
|
-
packages acme.tools 0.4.0 ✓ (@ 47f4b816) oats.okf 4.1.
|
|
108
|
+
packages acme.tools 0.4.0 ✓ (@ 47f4b816) oats.okf 4.1.1 ✓ (@ e1d604f7)
|
|
109
109
|
changed acme.tools — → 0.4.0 (@ 47f4b816)
|
|
110
110
|
souls 9 discovered (6 members, 1 external, 2 package, 0 disabled here) · 0 private capabilities
|
|
111
111
|
teams platform (shared) · this deployment's: oats teams
|
|
@@ -160,8 +160,8 @@ same workspace commit hold identical locks.
|
|
|
160
160
|
"source": "catalog:oats.okf",
|
|
161
161
|
"url": "https://github.com/awebai/oats-okf.git",
|
|
162
162
|
"path": "oats-package",
|
|
163
|
-
"version": "4.1.
|
|
164
|
-
"commit": "
|
|
163
|
+
"version": "4.1.1",
|
|
164
|
+
"commit": "e1d604f70c5e4cdc39602095f139383e61f69323",
|
|
165
165
|
"integrity": "sha256-…",
|
|
166
166
|
"capabilities": ["oats.okf", "oats.okf-harvest", "oats.okf-maintenance"]
|
|
167
167
|
},
|
|
@@ -331,12 +331,12 @@ A soul that names one of the package's capabilities with
|
|
|
331
331
|
{
|
|
332
332
|
"policy": "docs/official-catalog.md",
|
|
333
333
|
"packages": {
|
|
334
|
-
"oats.okf": { "url": "https://github.com/awebai/oats-okf.git", "ref": "v4.1.
|
|
335
|
-
"oats.framework": { "url": "https://github.com/awebai/oats.git", "ref": "oats-framework/v1.4.
|
|
334
|
+
"oats.okf": { "url": "https://github.com/awebai/oats-okf.git", "ref": "v4.1.1", "path": "oats-package" },
|
|
335
|
+
"oats.framework": { "url": "https://github.com/awebai/oats.git", "ref": "oats-framework/v1.4.2", "path": "oats-package" }
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
```
|
|
339
339
|
|
|
340
|
-
`ref` carries the tag convention: a workspace's `oats.framework: v1.4.
|
|
341
|
-
resolves to tag `oats-framework/v1.4.
|
|
340
|
+
`ref` carries the tag convention: a workspace's `oats.framework: v1.4.2`
|
|
341
|
+
resolves to tag `oats-framework/v1.4.2`. Resolving through the catalog never
|
|
342
342
|
advances a lock by itself: `oats sync` does, and says so.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# OATS 0.36.1
|
|
2
|
+
|
|
3
|
+
## Changed
|
|
4
|
+
|
|
5
|
+
- **oats.okf 4.1.1** (catalog and workspace pin, and the bundled mirrors):
|
|
6
|
+
three fixes to harvest completion and `harvest --once`.
|
|
7
|
+
- `oats okf complete` on an amended PR that is still open
|
|
8
|
+
(awebai/oats-okf#36). After the knowledge-maintainer pushed an amendment
|
|
9
|
+
on top of the delivered commit, `complete --run <id>` failed with `E_PR:
|
|
10
|
+
publication branch has unexpected commit; never force push`. The run is
|
|
11
|
+
now reported `delivered` when the known PR is open at the branch's tip
|
|
12
|
+
and Git shows that tip descends from the delivered commit; the answer
|
|
13
|
+
names the amended head. A tip that does not contain the delivered commit
|
|
14
|
+
is still refused with `E_PR`, and nothing is ever force-pushed. Ancestry
|
|
15
|
+
is read from the commit objects alone, so a checkout's grafts or
|
|
16
|
+
commit-graph file cannot fake it.
|
|
17
|
+
- `harvest --once`: one-shots of a seat no longer race
|
|
18
|
+
(awebai/oats-okf#39). The overlap checks and the install run under one
|
|
19
|
+
seat lock, so of two overlapping one-shots started together one installs
|
|
20
|
+
and the other gets `E_ONCE_OVERLAP`.
|
|
21
|
+
- `harvest --once`: a note edited between runs no longer strands a
|
|
22
|
+
draining one-shot (awebai/oats-okf#40). A rerun with the same manifest
|
|
23
|
+
continues from custody without reading the listed notes. Another
|
|
24
|
+
manifest listing a note a one-shot already holds is refused with
|
|
25
|
+
`E_ONCE_OVERLAP`, naming that one-shot, instead of a `sha256 mismatch`.
|
|
26
|
+
- **Preparing for team model 3** (awebai/oats#485). OATS 0.37.0 commits the
|
|
27
|
+
teams an organisation's souls may join, and their default team, in the
|
|
28
|
+
workspace file, closed by default (awebai/oats#484), so the organisation's
|
|
29
|
+
intended team set is visible and reviewable in its git and a deployment's
|
|
30
|
+
`oats-local.yaml` no longer adds a team by accident. 0.36.1 lets every workspace and
|
|
31
|
+
deployment migrate before 0.37.0 refuses the old shape:
|
|
32
|
+
- `oats-workspace.yaml` accepts `defaultTeam`, `localTeams` and `souls:`,
|
|
33
|
+
and validates them: every label they name must be a shared team in
|
|
34
|
+
`teams:` of the same file (`E_WORKSPACE_SCHEMA` otherwise, when the file
|
|
35
|
+
is read). 0.36.1 does **not** apply them: a soul's teams and default are
|
|
36
|
+
still resolved from `oats-local.yaml`. Earlier releases refuse these keys,
|
|
37
|
+
so add them only once everyone who reads the workspace runs 0.36.1 or
|
|
38
|
+
later.
|
|
39
|
+
- A new readiness warning, `team-model-3-migration` (never blocking), names
|
|
40
|
+
what 0.37.0 will refuse. `oats teams`, `oats readiness` (and so the
|
|
41
|
+
Desktop's readiness view) and `oats doctor` show it. Its `condition` is
|
|
42
|
+
`local-soul-teams` when `oats-local.yaml` has `souls.teams` or
|
|
43
|
+
`souls.default`, and `local-teams-closed` when `oats-local.yaml` declares
|
|
44
|
+
`teams` or `defaultTeam` and the workspace file does not say
|
|
45
|
+
`localTeams: true` (never in the standalone view). `oats doctor` stays
|
|
46
|
+
offline: it checks `local-teams-closed` against the workspace file this
|
|
47
|
+
machine last observed, and says so when there is none yet (`oats sync`
|
|
48
|
+
fixes that). The shapes are in docs/desktop-cli-api.md, under Team
|
|
49
|
+
readiness items.
|
|
50
|
+
- **oats.framework 1.4.2** (oats.setup 2.2.1; catalog and workspace pin
|
|
51
|
+
`oats-framework/v1.4.2`) ships the oats.setup skill changes made since
|
|
52
|
+
1.4.1, which deployments had not received:
|
|
53
|
+
- `oats-onboarding`: declare how this machine starts a harness once, as
|
|
54
|
+
that harness's default launch configuration (0.32.0, awebai/oats#368);
|
|
55
|
+
`oats spawn --preview` names the launch configuration that applies.
|
|
56
|
+
- `oats-workspace-config`: a soul's launch preference versus a host launch
|
|
57
|
+
configuration, `E_LAUNCH_CONFIG_INVALID` and `E_CLAUDE_CONFIG_REMOVED`
|
|
58
|
+
(awebai/oats#368), and the team model 3 workspace keys `defaultTeam`,
|
|
59
|
+
`localTeams` and `souls:` (awebai/oats#495).
|
|
60
|
+
- `oats-teams`: preparing for team model 3, and what each
|
|
61
|
+
`team-model-3-migration` condition asks for (awebai/oats#495).
|
|
62
|
+
- `oats-package-pins`: the example pins `oats.okf: v4.1.1`
|
|
63
|
+
(awebai/oats#494).
|
|
64
|
+
|
|
65
|
+
## What 0.37.0 will change
|
|
66
|
+
|
|
67
|
+
- **`souls:` in `oats-workspace.yaml` decides which teams a soul may join**
|
|
68
|
+
besides its default: the most specific key wins (`<member|package>/<soul>`,
|
|
69
|
+
then `<member|package>/*`, then `"*"`); `teams` is a list of shared labels
|
|
70
|
+
or `any`. A soul no key matches joins its default only. This applies to
|
|
71
|
+
package souls too: a workspace opens a package explicitly.
|
|
72
|
+
- **A soul's default team**, in order: its `souls:` `default`; else the
|
|
73
|
+
deployment's `defaultTeam`, only when the workspace says
|
|
74
|
+
`localTeams: true`; else the workspace's `defaultTeam`.
|
|
75
|
+
- **`oats-local.yaml` `souls.teams` and `souls.default` are refused**
|
|
76
|
+
(`E_WORKSPACE_SCHEMA`, reason `removed-key`), and so are `oats soul teams
|
|
77
|
+
--add/--remove/--default/--clear-default`.
|
|
78
|
+
- **Local `teams` and `defaultTeam` are refused unless the workspace says
|
|
79
|
+
`localTeams: true`**, and so are `oats teams add/remove/default`. The
|
|
80
|
+
standalone view still allows them.
|
|
81
|
+
|
|
82
|
+
## Upgrade
|
|
83
|
+
|
|
84
|
+
Nothing is required for 0.36.1 itself. To be ready for 0.37.0
|
|
85
|
+
(`oats teams` lists each deployment's `team-model-3-migration` warnings):
|
|
86
|
+
|
|
87
|
+
1. **Now**, once everyone who reads the workspace runs 0.36.1 or later,
|
|
88
|
+
commit in `oats-workspace.yaml` the choices each deployment makes locally:
|
|
89
|
+
- a `souls:` entry for what `souls.teams` says (`"*": { teams: [...] }`
|
|
90
|
+
for every soul, `<member|package>/<soul>: { teams: [...] }` for one;
|
|
91
|
+
local keys are bare soul names, workspace keys are qualified by the
|
|
92
|
+
member or package, as in `souls.disabled`), with a `default:` for what
|
|
93
|
+
`souls.default` says;
|
|
94
|
+
- for local teams and a local `defaultTeam`, choose one: (a) keep them
|
|
95
|
+
personal, and add `localTeams: true`, which clears `local-teams-closed`
|
|
96
|
+
at once; or (b) commit the teams in `teams:` and the default as
|
|
97
|
+
`defaultTeam:`.
|
|
98
|
+
2. **When the deployment moves to 0.37.0**, remove from its `oats-local.yaml`
|
|
99
|
+
`souls.teams`, `souls.default` and, under (b), the local `teams` and
|
|
100
|
+
`defaultTeam`. Not before: 0.36.1 does not apply the workspace keys, so
|
|
101
|
+
those local keys are still what decides a soul's teams and default until
|
|
102
|
+
then, and their warnings stay until they go. 0.37.0 refuses them, naming
|
|
103
|
+
the replacement.
|
|
@@ -152,8 +152,8 @@ composed skills and instructions, a spawn records:
|
|
|
152
152
|
"commit": "3f2a9c1e…", "digest": "sha256-…", "materializedAt": "2026-09-24T10:12:44.118Z"
|
|
153
153
|
},
|
|
154
154
|
"oats.okf": {
|
|
155
|
-
"from": { "kind": "package", "package": "oats.okf", "version": "4.1.
|
|
156
|
-
"commit": "
|
|
155
|
+
"from": { "kind": "package", "package": "oats.okf", "version": "4.1.1", "commit": "e1d604f7…", "integrity": "sha256-…", "repoKey": "github.com/awebai/oats-okf" },
|
|
156
|
+
"commit": "e1d604f7…", "digest": "sha256-…", "materializedAt": "2026-09-24T10:12:44.201Z"
|
|
157
157
|
}
|
|
158
158
|
},
|
|
159
159
|
"providers": {
|
package/docs/workspaces.md
CHANGED
|
@@ -54,8 +54,8 @@ members: # repo refs, NO @revision (E_WORKSPAC
|
|
|
54
54
|
- git:github.com/acme/tools # a member that ALSO publishes a package (see below)
|
|
55
55
|
|
|
56
56
|
packages: # the ONLY versioned things
|
|
57
|
-
oats.framework: v1.4.
|
|
58
|
-
oats.okf: v4.1.
|
|
57
|
+
oats.framework: v1.4.2 # bare version → resolves through the official catalog
|
|
58
|
+
oats.okf: v4.1.1
|
|
59
59
|
acme.tools: git:github.com/acme/tools@v0.4.0 # outside the catalog → git:<repo>@<tag|OID>; still a package
|
|
60
60
|
|
|
61
61
|
teams: # SHARED teams: the same provider team for everyone
|
|
@@ -359,6 +359,39 @@ there is no default; `team-unmapped`, blocking when it is the default;
|
|
|
359
359
|
its environment — see [capabilities.md](capabilities.md#teams-in-the-provider-environment).
|
|
360
360
|
Exact shapes: [desktop-cli-api.md](desktop-cli-api.md#team-model-v2-feature-team-model-2-oats-0300-replaces-feature-teams).
|
|
361
361
|
|
|
362
|
+
### Preparing for team model 3 (0.36.x)
|
|
363
|
+
|
|
364
|
+
OATS 0.37.0 commits a soul's teams in the workspace (team model 3,
|
|
365
|
+
awebai/oats#484): the teams an organisation's instances may join become its
|
|
366
|
+
own decision, visible and reviewable in its git, so a deployment's
|
|
367
|
+
`oats-local.yaml` no longer adds one by accident. 0.36.x prepares for it, so
|
|
368
|
+
every workspace and deployment can migrate first:
|
|
369
|
+
|
|
370
|
+
- **`oats-workspace.yaml` accepts the new keys** and validates them, but
|
|
371
|
+
**does not apply them**: a soul's teams and default are still resolved as
|
|
372
|
+
above, from `oats-local.yaml`.
|
|
373
|
+
|
|
374
|
+
```yaml
|
|
375
|
+
defaultTeam: engineering # the workspace's fallback default team
|
|
376
|
+
localTeams: true # deployments may declare their own teams (absent: false)
|
|
377
|
+
souls: # per pattern: "*", <member|package>/*, <member|package>/<soul>
|
|
378
|
+
"*": { teams: [] } # default only ({} says the same)
|
|
379
|
+
security-souls/*: { default: security, teams: [engineering] }
|
|
380
|
+
oats.engineering/*: { teams: any } # every shared team
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
`<member|package>` is the name `souls.disabled` uses. Every label (`defaultTeam`,
|
|
384
|
+
a `souls:` `default`, each of its `teams`) must be a shared team in `teams:` of
|
|
385
|
+
the same file; anything else is `E_WORKSPACE_SCHEMA` when the file is read. A
|
|
386
|
+
key naming a member or package the workspace does not have is not an error.
|
|
387
|
+
- **The readiness warning `team-model-3-migration`** (never blocking) names
|
|
388
|
+
what 0.37.0 will refuse: `souls.teams` / `souls.default` in `oats-local.yaml`
|
|
389
|
+
(they move to `souls:`), and local `teams` / `defaultTeam` while the workspace
|
|
390
|
+
does not say `localTeams: true` (fix: add `localTeams: true`, or commit the
|
|
391
|
+
teams and `defaultTeam` in the workspace file). `oats teams`, readiness (and
|
|
392
|
+
so the Desktop) and `oats doctor` show it. The migration steps are in the
|
|
393
|
+
[0.36.1 release notes](release-notes/v0.36.1.md).
|
|
394
|
+
|
|
362
395
|
## Provider payloads have three homes
|
|
363
396
|
|
|
364
397
|
| What it is | Where | Example |
|
package/lib/teams.mjs
CHANGED
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
* Rows (docs/desktop-cli-api.md, Team model v2): TeamRow { label, team, default, from: shared|local },
|
|
18
18
|
* the default first, then by label. Reports carry unmapped rows (team null); OATS_TEAMS and
|
|
19
19
|
* instance.json carry mapped rows only. DefaultTeam { label, team, from: deployment|soul } | null.
|
|
20
|
+
*
|
|
21
|
+
* Team model 3 (0.37.0, awebai/oats#484) moves these choices into the committed workspace file. 0.36.x
|
|
22
|
+
* validates its keys (lib/workspace.mjs) without applying them, and warns about what 0.37.0 will refuse
|
|
23
|
+
* (migrationProblems: team-model-3-migration).
|
|
20
24
|
*/
|
|
21
25
|
import { oatsError } from "./errors.mjs";
|
|
22
26
|
|
|
@@ -53,11 +57,19 @@ export function teamModel(workspace, local, { workspaceKey = null } = {}) {
|
|
|
53
57
|
localTeams.set(label, { label, team: str(def?.team), description: str(def?.description), from: "local", at: `${LOCAL_FILE}#/teams/${pointerKey(label)}` });
|
|
54
58
|
}
|
|
55
59
|
const souls = isObject(local?.souls) ? local.souls : {};
|
|
60
|
+
const has = (v, k) => isObject(v) && Object.hasOwn(v, k);
|
|
56
61
|
return {
|
|
57
62
|
shared, local: localTeams,
|
|
58
63
|
labels: new Map([...localTeams, ...shared]), // the committed definition wins a collision
|
|
59
64
|
defaultTeam: str(local?.defaultTeam),
|
|
60
65
|
souls: { teams: isObject(souls.teams) ? souls.teams : {}, default: isObject(souls.default) ? souls.default : {} },
|
|
66
|
+
// Team model 3 (0.37.0) moves these keys; 0.36.x only warns (migrationProblems). `localTeams` is
|
|
67
|
+
// the workspace's answer, null without a workspace file (the standalone view has no workspace rules).
|
|
68
|
+
migration: {
|
|
69
|
+
soulKeys: ["teams", "default"].filter((k) => has(local?.souls, k)).map((k) => `souls.${k}`),
|
|
70
|
+
teamKeys: ["teams", "defaultTeam"].filter((k) => has(local, k)),
|
|
71
|
+
localTeams: isObject(workspace) ? workspace.localTeams === true : null,
|
|
72
|
+
},
|
|
61
73
|
};
|
|
62
74
|
}
|
|
63
75
|
|
|
@@ -130,6 +142,27 @@ const unconfiguredProblem = () => ({ code: "E_TEAM_UNCONFIGURED", severity: "fai
|
|
|
130
142
|
const refusalProblem = (e) => ({ code: e.code, ...e.details, severity: "failure", message: e.message,
|
|
131
143
|
fix: e.code === "E_TEAM_UNKNOWN" ? "declare the team (`oats teams add`), or remove the reference" : "add the label to the soul's teams (`oats soul teams … --add`), or clear its default (`--clear-default`)" });
|
|
132
144
|
|
|
145
|
+
/** The fields of a team-model-3-migration problem other than code/severity/message/fix, as every
|
|
146
|
+
* surface (oats teams, readiness, doctor) carries them. */
|
|
147
|
+
export const MIGRATION_CODE = "team-model-3-migration";
|
|
148
|
+
/**
|
|
149
|
+
* The team-model-3-migration warnings (0.36.x; 0.37.0 refuses what they name): `local-soul-teams` when
|
|
150
|
+
* oats-local.yaml has souls.teams / souls.default, `local-teams-closed` when it declares teams /
|
|
151
|
+
* defaultTeam and the workspace file does not say `localTeams: true` (never without a workspace file).
|
|
152
|
+
*/
|
|
153
|
+
export function migrationProblems(model) {
|
|
154
|
+
const m = model.migration, problems = [];
|
|
155
|
+
if (m.soulKeys.length) problems.push({ code: MIGRATION_CODE, severity: "warning", condition: "local-soul-teams", keys: [...m.soulKeys],
|
|
156
|
+
message: `oats-local.yaml ${m.soulKeys.join(", ")}: OATS 0.37.0 refuses ${m.soulKeys.length > 1 ? "these keys" : "this key"}; which teams a soul may join, and its default, move to souls: in oats-workspace.yaml`,
|
|
157
|
+
fix: `commit the same choices as souls: entries in oats-workspace.yaml ("*" or <member|package>/<soul>: { default, teams }), then remove ${m.soulKeys.join(" and ")} from oats-local.yaml` });
|
|
158
|
+
if (m.teamKeys.length && m.localTeams === false) problems.push(localTeamsClosedProblem(m.teamKeys));
|
|
159
|
+
return problems;
|
|
160
|
+
}
|
|
161
|
+
/** `local-teams-closed` for the oats-local.yaml `keys` found (doctor builds it from its offline read). */
|
|
162
|
+
export const localTeamsClosedProblem = (keys) => ({ code: MIGRATION_CODE, severity: "warning", condition: "local-teams-closed", keys: [...keys],
|
|
163
|
+
message: `oats-local.yaml declares ${keys.join(", ")}, but oats-workspace.yaml does not say localTeams: true: OATS 0.37.0 refuses local teams and a local defaultTeam unless the workspace allows them`,
|
|
164
|
+
fix: "either (a) add `localTeams: true` to oats-workspace.yaml, or (b) commit the teams and defaultTeam in oats-workspace.yaml, then remove them from oats-local.yaml" });
|
|
165
|
+
|
|
133
166
|
/**
|
|
134
167
|
* Readiness problems. Without `key`: the deployment's (`oats teams`): collisions, unmapped shared
|
|
135
168
|
* teams (a failure when it is `defaultTeam`), every unknown reference, every ineligible
|
|
@@ -141,11 +174,11 @@ export function teamProblems(model, { key = null, messaging = false } = {}) {
|
|
|
141
174
|
if (key !== null) {
|
|
142
175
|
let t;
|
|
143
176
|
try { t = soulTeams(model, key); }
|
|
144
|
-
catch (e) { if (e.code === "E_TEAM_UNKNOWN" || e.code === "E_TEAM_NOT_ELIGIBLE") return [refusalProblem(e)]; throw e; }
|
|
177
|
+
catch (e) { if (e.code === "E_TEAM_UNKNOWN" || e.code === "E_TEAM_NOT_ELIGIBLE") return [refusalProblem(e), ...migrationProblems(model)]; throw e; }
|
|
145
178
|
for (const r of t.teams) if (model.shared.has(r.label) && model.local.has(r.label)) problems.push(collisionProblem(r.label, model.shared.get(r.label), model.local.get(r.label)));
|
|
146
179
|
for (const r of t.teams) if (r.team === null) problems.push(unmappedProblem(model.labels.get(r.label), r.default));
|
|
147
180
|
if (messaging && t.defaultTeam === null) problems.push(unconfiguredProblem());
|
|
148
|
-
return problems;
|
|
181
|
+
return [...problems, ...migrationProblems(model)];
|
|
149
182
|
}
|
|
150
183
|
const labels = [...model.labels.keys()].sort(byCodepoint);
|
|
151
184
|
for (const label of labels) if (model.shared.has(label) && model.local.has(label)) problems.push(collisionProblem(label, model.shared.get(label), model.local.get(label)));
|
|
@@ -159,7 +192,7 @@ export function teamProblems(model, { key = null, messaging = false } = {}) {
|
|
|
159
192
|
try { soulTeams(model, k); } catch (e) { if (e.code === "E_TEAM_NOT_ELIGIBLE" && e.details.soul === k) problems.push(refusalProblem(e)); else if (e.code !== "E_TEAM_UNKNOWN") throw e; }
|
|
160
193
|
}
|
|
161
194
|
if (messaging && model.defaultTeam === null) problems.push(unconfiguredProblem());
|
|
162
|
-
return problems;
|
|
195
|
+
return [...problems, ...migrationProblems(model)];
|
|
163
196
|
}
|
|
164
197
|
|
|
165
198
|
/**
|
package/lib/workspace.mjs
CHANGED
|
@@ -243,8 +243,22 @@ export function validateWorkspace(value, { remote = defaultRemote } = {}) {
|
|
|
243
243
|
const d = value.defaults;
|
|
244
244
|
for (const slot of ["knowledge", "messaging", "tasks", "capabilities"]) fromProblems(remote, d[slot], `/defaults/${slot}`, problems, { here: false });
|
|
245
245
|
}
|
|
246
|
+
sharedLabelProblems(value, problems);
|
|
246
247
|
return withRemovedKeys(problems, value, REMOVED_KEYS.workspace);
|
|
247
248
|
}
|
|
249
|
+
/** Team model 3: every label `defaultTeam` and `souls:` name is a shared team of this same file, so an
|
|
250
|
+
* unknown label is refused when the file is read, never at a spawn on someone else's machine. */
|
|
251
|
+
function sharedLabelProblems(value, problems) {
|
|
252
|
+
const shared = new Set(isObject(value.teams) ? Object.keys(value.teams) : []);
|
|
253
|
+
const known = (label, path) => { if (typeof label === "string" && !shared.has(label)) problems.push({ path, message: `${show(label)} is not a shared team: declare it in teams: of this file` }); };
|
|
254
|
+
known(value.defaultTeam, "/defaultTeam");
|
|
255
|
+
if (isObject(value.souls)) for (const [key, entry] of Object.entries(value.souls)) {
|
|
256
|
+
if (!isObject(entry)) continue;
|
|
257
|
+
const at = `/souls/${pointerKey(key)}`;
|
|
258
|
+
known(entry.default, `${at}/default`);
|
|
259
|
+
if (Array.isArray(entry.teams)) entry.teams.forEach((label, i) => known(label, `${at}/teams/${i}`));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
248
262
|
export function validateMembership(value) { return withRemovedKeys(validateAgainst(schemaFor("membership"), value), value, REMOVED_KEYS.membership); }
|
|
249
263
|
|
|
250
264
|
/** Keys 0.30 removed (team model v2): each is a schema problem naming its replacement, in place of
|
package/package-catalog.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"packages": {
|
|
4
4
|
"oats.okf": {
|
|
5
5
|
"url": "https://github.com/awebai/oats-okf.git",
|
|
6
|
-
"ref": "v4.1.
|
|
6
|
+
"ref": "v4.1.1",
|
|
7
7
|
"path": "oats-package"
|
|
8
8
|
},
|
|
9
9
|
"oats.aweb": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"oats.framework": {
|
|
35
35
|
"url": "https://github.com/awebai/oats.git",
|
|
36
|
-
"ref": "oats-framework/v1.4.
|
|
36
|
+
"ref": "oats-framework/v1.4.2",
|
|
37
37
|
"path": "oats-package"
|
|
38
38
|
}
|
|
39
39
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awebai/oats",
|
|
3
|
-
"version": "0.36.
|
|
3
|
+
"version": "0.36.1",
|
|
4
4
|
"description": "OATS (Open Agent Team Specification) — durable souls, disposable instances, targetable capability packages, and the runtime-neutral oats CLI/kernel.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -60,8 +60,8 @@ members:
|
|
|
60
60
|
- git:github.com/acme/agents # the host is a member too
|
|
61
61
|
- git:github.com/acme/platform
|
|
62
62
|
packages:
|
|
63
|
-
oats.framework: v1.4.
|
|
64
|
-
oats.okf: v4.1.
|
|
63
|
+
oats.framework: v1.4.2 # bare versions resolve through the official catalog
|
|
64
|
+
oats.okf: v4.1.1
|
|
65
65
|
defaults:
|
|
66
66
|
capabilities: { oats.core: { from: package } }
|
|
67
67
|
knowledge: { oats.okf: { from: package } }
|