@awebai/oats 0.24.12 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/bin/oats.mjs +936 -2822
  2. package/docs/capabilities.md +136 -323
  3. package/docs/configuration.md +68 -533
  4. package/docs/design/2026-09-16-fresh-operator-walkthrough.md +19 -14
  5. package/docs/design/2026-09-16-portable-migration-evidence.md +2 -0
  6. package/docs/design/2026-09-16-portable-onboarding.md +4 -2
  7. package/docs/design/2026-09-20-redesign-program-board.md +1 -1
  8. package/docs/design/2026-09-20-workspace-and-portable-adoption-plan.md +2 -0
  9. package/docs/design/2026-09-23-simplified-workspace-model.md +711 -0
  10. package/docs/design/2026-09-23-workspace-module-contracts.md +309 -0
  11. package/docs/design/2026-09-23-workspace-v2-implementation-plan.md +65 -0
  12. package/docs/design/README.md +20 -8
  13. package/docs/design/operations-contract.md +1 -0
  14. package/docs/design/package-engine-contract.md +1 -1
  15. package/docs/design/package-runtime-api.md +1 -1
  16. package/docs/desktop-cli-api.md +386 -6
  17. package/docs/desktop-succession.md +3 -4
  18. package/docs/first-team.md +107 -224
  19. package/docs/implementation.md +6 -4
  20. package/docs/integrations.md +45 -44
  21. package/docs/knowledge-capability-authoring.md +10 -4
  22. package/docs/knowledge-migration.md +5 -4
  23. package/docs/knowledge-reference/package-craft.md +11 -3
  24. package/docs/knowledge.md +24 -8
  25. package/docs/layers.md +3 -3
  26. package/docs/oats-local.schema.json +50 -0
  27. package/docs/oats-membership.schema.json +23 -0
  28. package/docs/oats-workspace.schema.json +133 -48
  29. package/docs/official-marketplace.md +9 -6
  30. package/docs/packages.md +229 -440
  31. package/docs/rebuild-to-v2.md +233 -0
  32. package/docs/release-notes/v0.24.13.md +51 -0
  33. package/docs/release-notes/v0.25.0.md +99 -0
  34. package/docs/soul.schema.json +41 -68
  35. package/docs/souls-and-instances.md +175 -108
  36. package/docs/workspace-adoption.md +70 -345
  37. package/docs/workspaces.md +429 -119
  38. package/lib/core.mjs +419 -55
  39. package/lib/instance-resolution.mjs +312 -0
  40. package/lib/materialize.mjs +580 -0
  41. package/lib/packages.mjs +501 -1273
  42. package/lib/remote.mjs +639 -0
  43. package/lib/resolve.mjs +576 -0
  44. package/lib/schedule.mjs +194 -34
  45. package/lib/workspace.mjs +635 -0
  46. package/package.json +1 -1
  47. package/lib/portable-migration-artifacts.mjs +0 -135
  48. package/lib/portable-migration-evidence.mjs +0 -305
  49. package/lib/portable-migration-store.mjs +0 -199
  50. package/lib/portable-migration.mjs +0 -104
  51. package/lib/portable-onboarding-acceptance.mjs +0 -66
  52. package/lib/setup-expert-source.mjs +0 -100
package/docs/layers.md CHANGED
@@ -34,8 +34,8 @@ Classic `kind`/`type`/`repo` declarations and config-targeted agent types are a
34
34
 
35
35
  ## Workspace, repository and adoption contracts
36
36
 
37
- - `oats-workspace.yaml` declares intended members, defaults, imports and optional provider-owned stores/team/catalog references.
38
- - `oats.yaml` advertises a repository's actual soul/package/knowledge exports and, for membership, a workspace backlink.
37
+ - `oats-workspace.yaml` (v2) declares members, the pinned `packages:`, team labels, defaults per slot and per team, stores, the messaging payload and pinned `external:` souls.
38
+ - `oats-membership.yaml` is a repository's half of the handshake: the workspace backlink plus an optional default team label. Everything under `souls/` and `capabilities/` is discoverable by convention (`private: true` opts out); there are no export lists.
39
39
  - Membership requires compatible observations on both sides; folder adjacency or a copied declaration is not admission.
40
40
  - External source import does not adopt the publisher's workspace. A framework repository may host its own development workspace without imposing it on consumers.
41
41
  - Operator choices and workspace defaults must respect source requirements. Git read access is not write permission, executable approval or messaging enrollment.
@@ -96,7 +96,7 @@ The work target is independent of source publication and knowledge placement. Pr
96
96
 
97
97
  ## Kernel briefings versus operational capabilities
98
98
 
99
- The kernel owns only what describes the layout it creates: the `instance-boundary` briefing (home versus `work/`), the selected work-mode briefing and config-declared injections. Knowing how to *operate* OATS (status, spawn, retire, soul discovery) and how to *configure* it (workspaces, packages, trust) is capability content — accepted as the official capabilities `oats.core` (explicit default on every soul, removable) and `oats.setup` (held by the onboarding-created `oats-setup-expert`). At the0.24 baseline those skills are still kernel-shipped; see the [workspace guide](workspaces.md#how-a-soul-knows-oats-accepted-direction-not-yet-shipped) and the adoption plan's distribution packages.
99
+ The kernel owns only what describes the layout it creates: the `instance-boundary` briefing (home versus `work/`), the selected work-mode briefing and config-declared injections. Knowing how to *operate* OATS (status, spawn, retire, soul discovery) and how to *configure* it (workspaces, packages, approval) is capability content — the official capabilities `oats.core` (a workspace default via `defaults.capabilities`, removable per soul with `off`) and `oats.setup` (held by an onboarding expert), both provided by the `oats.framework` package; see [souls and instances](souls-and-instances.md#oats-operational-knowledge-is-a-capability).
100
100
 
101
101
  ## Capture and knowledge are separate
102
102
 
@@ -0,0 +1,50 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://oats.dev/schemas/local-v2.json",
4
+ "title": "Deployment-local overrides v2 (oats-local.yaml)",
5
+ "description": "The operator's side of a workspace: which workspace this machine realizes, where member clones live when not at the taught convention, host-owned capability settings (absolute paths belong HERE, never in the workspace file), and souls disabled on this machine. Never shared through Git.",
6
+ "type": "object",
7
+ "required": ["schemaVersion", "workspace"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "schemaVersion": { "const": 2 },
11
+ "workspace": {
12
+ "type": "string",
13
+ "minLength": 1,
14
+ "pattern": "^(?:git@[^@\\s]+|[^@\\s]+)$",
15
+ "description": "Repo ref of the workspace host; observed over the remote, need not be cloned."
16
+ },
17
+ "standalone": {
18
+ "type": "string",
19
+ "minLength": 1,
20
+ "pattern": "^(?:git@[^@\\s]+|[^@\\s]+)$",
21
+ "description": "Repo ref to realize in the STANDALONE view (decision 10): its own souls and from: here capabilities plus oats.core (decision 25), no workspace lookup. Use when the repo's workspace cannot be read; `workspace:` still names the repo you point the kernel at."
22
+ },
23
+ "clones": {
24
+ "type": "object",
25
+ "propertyNames": { "type": "string", "pattern": "^[^\\s@/][^\\s@]*/[^\\s@]+$" },
26
+ "additionalProperties": { "type": "string", "minLength": 1 },
27
+ "description": "<repo key>: <path on this machine> for member clones outside the convention."
28
+ },
29
+ "settings": {
30
+ "type": "object",
31
+ "propertyNames": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*$" },
32
+ "additionalProperties": {
33
+ "type": "object",
34
+ "propertyNames": { "type": "string", "pattern": "^[A-Za-z][A-Za-z0-9_.-]*$" }
35
+ },
36
+ "description": "<capability>: { <key>: <value> } host-owned values the manifests ask for."
37
+ },
38
+ "souls": {
39
+ "type": "object",
40
+ "additionalProperties": false,
41
+ "properties": {
42
+ "disabled": {
43
+ "type": "array",
44
+ "uniqueItems": true,
45
+ "items": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://oats.dev/schemas/membership-v2.json",
4
+ "title": "Repository membership backlink v2 (oats-membership.yaml)",
5
+ "description": "The repo's half of the reciprocal handshake: it names the workspace it belongs to, plus an optional default team label for the repo's items. Nothing else. A backlink is consent, not admission — the workspace must list the repo too.",
6
+ "type": "object",
7
+ "required": ["schemaVersion", "workspace"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "schemaVersion": { "const": 2 },
11
+ "workspace": {
12
+ "type": "string",
13
+ "minLength": 1,
14
+ "pattern": "^(?:git@[^@\\s]+|[^@\\s]+)$",
15
+ "description": "Repo ref of the workspace host, without revision."
16
+ },
17
+ "team": {
18
+ "type": "string",
19
+ "pattern": "^[a-z0-9][a-z0-9._-]*$",
20
+ "description": "Default team label for souls and capabilities in this repo that carry no `team:` of their own."
21
+ }
22
+ }
23
+ }
@@ -1,68 +1,153 @@
1
1
  {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://oats.dev/schemas/workspace-v1.json",
4
- "title": "Portable workspace definition v1",
5
- "description": "Data shape only; hosting identity, reciprocal membership and provider readiness are verified separately.",
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://oats.dev/schemas/workspace-v2.json",
4
+ "title": "Workspace declaration v2 (oats-workspace.yaml)",
5
+ "description": "Data shape only. Members carry NO revision (a member is always its latest state); `external` sources REQUIRE a full 40-hex commit; absolute filesystem paths are refused anywhere in this file (host paths belong in oats-local.yaml). Reciprocal membership is observed over Git remotes, not declared here.",
6
6
  "type": "object",
7
7
  "required": ["schemaVersion", "name"],
8
8
  "additionalProperties": false,
9
9
  "properties": {
10
- "schemaVersion": { "const": 1 },
11
- "name": { "type": "string", "minLength": 1 },
12
- "members": { "type": "array", "items": { "$ref": "#/$defs/repository" } },
13
- "defaults": { "$ref": "https://oats.dev/schemas/soul-v1.json#/$defs/defaults" },
14
- "knowledge": {
15
- "type": "object", "required": ["stores"], "additionalProperties": false,
16
- "properties": { "stores": { "type": "array", "items": { "$ref": "https://oats.dev/schemas/soul-v1.json#/properties/knowledge" } } }
10
+ "schemaVersion": { "const": 2 },
11
+ "name": { "$ref": "#/$defs/slug" },
12
+ "members": {
13
+ "type": "array",
14
+ "uniqueItems": true,
15
+ "items": { "$ref": "#/$defs/memberRef" },
16
+ "description": "Repo refs without revision. Each becomes a member only when its oats-membership.yaml names this workspace back."
17
+ },
18
+ "packages": {
19
+ "type": "object",
20
+ "propertyNames": { "$ref": "#/$defs/packageId" },
21
+ "additionalProperties": { "$ref": "#/$defs/packageVersion" },
22
+ "description": "The ONLY versioned things: <package-id>: <version | git ref with @revision>."
17
23
  },
18
24
  "teams": {
19
- "type": "object", "propertyNames": { "$ref": "#/$defs/alias" },
20
- "properties": { "private": { "const": "per-human" } },
21
- "additionalProperties": {
22
- "type": "object", "required": ["provider", "id"], "additionalProperties": false,
23
- "properties": { "provider": { "$ref": "https://oats.dev/schemas/soul-v1.json#/$defs/capability" }, "id": { "type": "string", "minLength": 1 } }
24
- }
25
+ "type": "object",
26
+ "propertyNames": { "$ref": "#/$defs/label" },
27
+ "additionalProperties": { "$ref": "#/$defs/team" },
28
+ "description": "Org team labels. A label never gates, restricts or partitions anything."
29
+ },
30
+ "defaults": { "$ref": "#/$defs/defaults" },
31
+ "stores": {
32
+ "type": "object",
33
+ "propertyNames": { "$ref": "#/$defs/slug" },
34
+ "additionalProperties": { "$ref": "#/$defs/memberRef" },
35
+ "description": "Knowledge stores, declared once: <name>: <repo ref>."
25
36
  },
26
- "catalogs": {
27
- "type": "array", "items": {
28
- "type": "object", "required": ["source"], "additionalProperties": false,
29
- "properties": { "source": { "$ref": "#/$defs/source" }, "revision": { "$ref": "#/$defs/revision" }, "path": { "$ref": "#/$defs/path" } }
37
+ "messaging": {
38
+ "type": "object",
39
+ "description": "Opaque provider payload consumed by the messaging-slot capability. May carry byTeam: { <team label>: <payload> } — the kernel merges base ⊕ byTeam[soul.team] and strips byTeam before the provider sees it (decision 23).",
40
+ "properties": {
41
+ "byTeam": {
42
+ "type": "object",
43
+ "propertyNames": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
44
+ "additionalProperties": { "type": "object" }
45
+ }
30
46
  }
31
47
  },
32
- "imports": { "type": "array", "items": { "$ref": "#/$defs/import" } }
48
+ "external": {
49
+ "type": "array",
50
+ "items": { "$ref": "#/$defs/external" },
51
+ "description": "Souls adopted by reference from repos that are NOT members; pinned to a full commit."
52
+ }
33
53
  },
34
54
  "$defs": {
35
- "source": { "type": "string", "pattern": "^git:.+$" },
36
- "revision": { "type": "string", "minLength": 1 },
37
- "path": { "type": "string", "minLength": 1, "description": "Canonical contained repository-relative path; the shared source codec enforces semantic path rules." },
38
- "alias": { "type": "string", "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*$" },
39
- "repository": {
40
- "type": "object", "required": ["source"], "additionalProperties": false,
41
- "properties": { "source": { "$ref": "#/$defs/source" }, "revision": { "$ref": "#/$defs/revision" } }
55
+ "slug": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
56
+ "label": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*$" },
57
+ "capabilityName": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*$" },
58
+ "packageId": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]*$" },
59
+ "packageVersion": {
60
+ "type": "string",
61
+ "minLength": 1,
62
+ "pattern": "^(?:v?\\d+(?:\\.\\d+)*(?:[-+][0-9A-Za-z.-]+)?|git:(?:git@[^@\\s/:]+:)?[^@\\s]+@(?:[0-9a-f]{40}|(?!-)(?!.*(?:\\.\\.|@\\{|\\^|~|:|\\?|\\*|\\[|\\\\|\\.lock$|\\.$|/$|^/))[!-?A-~]+))$",
63
+ "description": "Exactly two forms: a bare version (v2.1.3) resolved through the catalog, or git:<repo>@<ref> (a direct package ref). lib/packages.mjs#classifyPackageValue is the full grammar."
64
+ },
65
+ "memberRef": {
66
+ "type": "string",
67
+ "minLength": 1,
68
+ "pattern": "^(?:git@[^@\\s]+|[^@\\s]+)$",
69
+ "description": "A repo ref (git:<host>/<path>, https://…, git@host:path.git, file:///…) with NO @revision."
70
+ },
71
+ "pinnedRef": {
72
+ "type": "string",
73
+ "pattern": "^(?:git@[^@\\s]+|[^@\\s]+)@[0-9a-f]{40}$",
74
+ "description": "<repo ref>@<full 40-hex commit OID>."
75
+ },
76
+ "repoKey": {
77
+ "type": "string",
78
+ "pattern": "^[^\\s@/][^\\s@]*/[^\\s@]+$",
79
+ "description": "Canonical repo identity <host>/<path> (or local/<abs-path> for file remotes), as produced by parseRepoRef(...).key."
42
80
  },
43
- "import": {
44
- "type": "object", "required": ["source", "soul", "revision", "alias"], "additionalProperties": false,
81
+ "fromLocation": {
82
+ "anyOf": [
83
+ { "const": "package" },
84
+ { "const": "here" },
85
+ { "$ref": "#/$defs/repoKey" }
86
+ ],
87
+ "description": "WHERE a capability comes from — a location, never a version."
88
+ },
89
+ "capabilityRef": {
90
+ "type": "object",
91
+ "required": ["from"],
92
+ "additionalProperties": false,
93
+ "properties": { "from": { "$ref": "#/$defs/fromLocation" } }
94
+ },
95
+ "capabilityChoice": { "anyOf": [{ "$ref": "#/$defs/capabilityRef" }, { "const": "off" }] },
96
+ "capabilityMap": {
97
+ "type": "object",
98
+ "propertyNames": { "$ref": "#/$defs/capabilityName" },
99
+ "additionalProperties": { "$ref": "#/$defs/capabilityChoice" }
100
+ },
101
+ "slotDefault": {
102
+ "anyOf": [
103
+ { "const": "none" },
104
+ {
105
+ "type": "object",
106
+ "maxProperties": 1,
107
+ "propertyNames": { "$ref": "#/$defs/capabilityName" },
108
+ "additionalProperties": { "$ref": "#/$defs/capabilityRef" }
109
+ }
110
+ ],
111
+ "description": "At most one capability fills a slot; `none` leaves it empty."
112
+ },
113
+ "team": {
114
+ "type": "object",
115
+ "additionalProperties": false,
116
+ "properties": { "description": { "type": "string" } }
117
+ },
118
+ "defaults": {
119
+ "type": "object",
120
+ "additionalProperties": false,
45
121
  "properties": {
46
- "source": { "$ref": "#/$defs/source" },
47
- "soul": { "$ref": "#/$defs/path" },
48
- "revision": { "$ref": "#/$defs/revision" },
49
- "alias": { "type": "string", "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
50
- "adoption": {
51
- "type": "object", "additionalProperties": false,
52
- "properties": {
53
- "teamAliases": { "type": "object", "propertyNames": { "$ref": "#/$defs/alias" }, "additionalProperties": { "$ref": "#/$defs/alias" } },
54
- "providers": {
55
- "type": "object", "additionalProperties": false,
56
- "properties": {
57
- "knowledge": { "$ref": "https://oats.dev/schemas/soul-v1.json#/$defs/defaultProvider" },
58
- "messaging": { "$ref": "https://oats.dev/schemas/soul-v1.json#/$defs/defaultProvider" },
59
- "tasks": { "$ref": "https://oats.dev/schemas/soul-v1.json#/$defs/defaultProvider" }
60
- }
61
- },
62
- "bindings": { "type": "object" }
122
+ "capabilities": { "$ref": "#/$defs/capabilityMap" },
123
+ "knowledge": { "$ref": "#/$defs/slotDefault" },
124
+ "messaging": { "$ref": "#/$defs/slotDefault" },
125
+ "tasks": { "$ref": "#/$defs/slotDefault" },
126
+ "byTeam": {
127
+ "type": "object",
128
+ "propertyNames": { "$ref": "#/$defs/label" },
129
+ "additionalProperties": {
130
+ "type": "object",
131
+ "additionalProperties": false,
132
+ "properties": { "capabilities": { "$ref": "#/$defs/capabilityMap" } }
63
133
  }
64
134
  }
65
135
  }
136
+ },
137
+ "external": {
138
+ "type": "object",
139
+ "required": ["source", "soul"],
140
+ "additionalProperties": false,
141
+ "properties": {
142
+ "source": { "$ref": "#/$defs/pinnedRef" },
143
+ "soul": {
144
+ "type": "string",
145
+ "minLength": 1,
146
+ "pattern": "^(?![A-Za-z]:)(?!/)(?!.*(?:^|/)\\.{1,2}(?:/|$))[^/\\\\\u0000]+(?:/[^/\\\\\u0000]+)*$",
147
+ "description": "Repository-relative directory holding the soul's soul.yaml."
148
+ },
149
+ "team": { "$ref": "#/$defs/label" }
150
+ }
66
151
  }
67
152
  }
68
153
  }
@@ -10,14 +10,17 @@ or workspace membership alone does not make a package official.
10
10
  - Browse the catalog for the kernel/source version you use. Each package entry
11
11
  identifies its repository, release ref and payload root; capability aliases
12
12
  can point to the package that supplies them.
13
- - Today, `oats install <capability-or-package-id>` resolves official short names
14
- through the CLI's catalog. For example, `oats install oats.okf --dir /absolute/scope`
15
- selects the listed package; it does not enroll a team or adopt
16
- the publisher's workspace. See [package operations](packages.md).
13
+ - A workspace pins an official package by **bare version** in its
14
+ `packages:` map (`oats.okf: v2.1.3`); `oats sync` resolves it through the
15
+ catalog to an exact commit, locks it and asks for executable approval once
16
+ per version. A package outside the catalog is written `git:<repo>@<ref>`.
17
+ Pinning does not enroll a team or adopt the publisher's workspace. See
18
+ [packages](packages.md).
17
19
  - The Desktop marketplace view/search is **planned for the parity phase**, not
18
20
  shipped by this policy or by OATS 0.24. There is no new marketplace CLI verb.
19
- - **Discoverable ≠ installed ≠ approved.** Acquisition and exact locking are
20
- separate from capability selection and per-capability executable approval.
21
+ - **Discoverable ≠ pinned ≠ approved.** A catalog listing grants nothing; a
22
+ `packages:` pin selects a version; the lock's per-version approval is what
23
+ lets its executables run. Nothing is installed.
21
24
  Official status never grants trust, credentials or permission to run code.
22
25
  - Listing also does not prove that every harness, provider combination or
23
26
  deployment profile is supported. Check the package's declared compatibility,