@awebai/oats 0.24.1 → 0.24.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/oats.mjs +163 -12
- package/capabilities/oats-aweb/bin/oats-aweb-binding.mjs +11 -0
- package/capabilities/oats-aweb/bin/oats-aweb.mjs +26 -0
- package/capabilities/oats-aweb/lib/binding-wire.mjs +214 -0
- package/capabilities/oats-aweb/lib/captured-execution.mjs +91 -0
- package/capabilities/oats-aweb/lib/captured-native.mjs +91 -0
- package/capabilities/oats-aweb/lib/invocation-shape.mjs +135 -0
- package/capabilities/oats-aweb/lib/portable-binding.mjs +146 -0
- package/capabilities/oats-aweb/lib/session-readiness.mjs +56 -0
- package/capabilities/oats-aweb/oats.json +12 -3
- package/docs/design/2026-09-20-redesign-program-board.md +28 -15
- package/docs/first-team.md +42 -0
- package/docs/layers.md +1 -1
- package/docs/official-marketplace.md +14 -9
- package/docs/packages.md +11 -7
- package/docs/release-notes/v0.24.2.md +21 -0
- package/docs/souls-and-instances.md +25 -0
- package/docs/workspace-adoption.md +94 -65
- package/injects/oats-portable.md +4 -0
- package/lib/core.mjs +46 -13
- package/lib/provider-binding-broker.mjs +6 -1
- package/lib/setup-expert-source.mjs +76 -0
- package/package-catalog.json +7 -4
- package/package.json +3 -1
- package/souls/oats-setup-expert/AGENTS.md +60 -0
- package/souls/oats-setup-expert/soul.yaml +14 -0
package/lib/core.mjs
CHANGED
|
@@ -51,6 +51,7 @@ import { buildCapturedInvocationContext, withCapturedInvocationContextFile } fro
|
|
|
51
51
|
import { readCapturedInstanceIndex, readCapturedInstanceMetadata, readCapturedInstanceAuthority, assertCapturedInstanceCustody,
|
|
52
52
|
recordCapturedCustodyFailure, markCapturedNativeScaffold, failCapturedNativeIntent, observeCapturedNativeTarget, setCapturedInstanceStatus, admitCapturedInstanceAction, beginCapturedIntent, settleCapturedIntent } from "./captured-instance-index.mjs";
|
|
53
53
|
import { validateExecutionBinding } from "./schedule-capsule.mjs";
|
|
54
|
+
import { parsePortableSource } from "./source-spec.mjs";
|
|
54
55
|
import { validateIntentRef } from "./captured-admission-shape.mjs";
|
|
55
56
|
export { readCapturedInstanceIndex, readCapturedInstanceMetadata, beginCapturedIntent, settleCapturedIntent };
|
|
56
57
|
export { buildCapturedInvocationContext, withCapturedInvocationContextFile };
|
|
@@ -112,6 +113,18 @@ export const OATS_VERSION = JSON.parse(readFileSync(join(PKG_ROOT, "package.json
|
|
|
112
113
|
/** Skills shipped with the kernel. Only oats-getting-started is ambient; spawn composes selected skills locally. */
|
|
113
114
|
export const PACKAGED_SKILLS_DIR = join(PKG_ROOT, "skills");
|
|
114
115
|
|
|
116
|
+
function soulRequirements(soulDir) {
|
|
117
|
+
const file = soulDir && join(soulDir, "soul.yaml");
|
|
118
|
+
return file && existsSync(file) ? withConfigFile(file, () => parseYamlNested(readFileSync(file, "utf8"))).requires : undefined;
|
|
119
|
+
}
|
|
120
|
+
function declaredOperationalCapabilities(soulDir) {
|
|
121
|
+
const capabilities = soulRequirements(soulDir)?.capabilities ?? {};
|
|
122
|
+
return ["oats.core", "oats.setup"].filter(id => Object.hasOwn(capabilities, id));
|
|
123
|
+
}
|
|
124
|
+
function legacyOperationalSkills(soulDir) {
|
|
125
|
+
return declaredOperationalCapabilities(soulDir).length ? [] : ["oats", "oats-config", "oats-packages"].map(name => ({ id: "kernel", path: join(PACKAGED_SKILLS_DIR, name) }));
|
|
126
|
+
}
|
|
127
|
+
|
|
115
128
|
// ---------- shell helpers ----------
|
|
116
129
|
function sh(cmdline) { return execSync(cmdline, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim(); }
|
|
117
130
|
function shTry(cmdline) { try { return sh(cmdline); } catch { return undefined; } }
|
|
@@ -4083,6 +4096,10 @@ export function composeInstanceAgentsMd(soulDir, contextDir, soulName, workMode,
|
|
|
4083
4096
|
if (!existsSync(agentsMd)) throw new Error(`canonical soul instructions missing: ${agentsMd}`);
|
|
4084
4097
|
const resolved = resolveOatsConfig(contextDir, soulName);
|
|
4085
4098
|
const wanted = [];
|
|
4099
|
+
const declaredOperations = declaredOperationalCapabilities(soulDir);
|
|
4100
|
+
const oatsCoreDeclared = declaredOperations.includes("oats.core");
|
|
4101
|
+
if (declaredOperations.length) resolved.kernelInjection = { inject: undefined,
|
|
4102
|
+
provenance: `declared ${declaredOperations.join(", ")} ${declaredOperations.length === 1 ? "capability" : "capabilities"}` };
|
|
4086
4103
|
const kernelInject = resolved.kernelInjection?.inject;
|
|
4087
4104
|
if (kernelInject && existsSync(kernelInject)) wanted.push(["kernel:oats", kernelInject]);
|
|
4088
4105
|
if (kind === "local") {
|
|
@@ -4104,7 +4121,7 @@ export function composeInstanceAgentsMd(soulDir, contextDir, soulName, workMode,
|
|
|
4104
4121
|
}
|
|
4105
4122
|
for (const inj of resolved.injects) wanted.push([`config:${inj.source}`, inj.file]);
|
|
4106
4123
|
const blocks = wanted.map(([source, file]) => ({ source, file, content: readFileSync(file, "utf8").trim() }));
|
|
4107
|
-
return { text: renderInstructionText(readFileSync(agentsMd, "utf8"), blocks), blocks, resolved };
|
|
4124
|
+
return { text: renderInstructionText(readFileSync(agentsMd, "utf8"), blocks), blocks, resolved, oatsCoreDeclared };
|
|
4108
4125
|
}
|
|
4109
4126
|
|
|
4110
4127
|
/** The skill entries a tree contributes — THE discovery rule, shared by preflight
|
|
@@ -4162,7 +4179,7 @@ export function planInstanceResources({ resolved, soulDir, agent, contextDir, co
|
|
|
4162
4179
|
}
|
|
4163
4180
|
};
|
|
4164
4181
|
|
|
4165
|
-
for (const path of
|
|
4182
|
+
for (const { path } of legacyOperationalSkills(soulDir)) {
|
|
4166
4183
|
add({ type: "skill-tree", source: "kernel", declared: basename(path), path: existsSync(path) ? path : undefined });
|
|
4167
4184
|
}
|
|
4168
4185
|
const soulSkills = soulDir && join(soulDir, "skills");
|
|
@@ -5110,15 +5127,31 @@ export function resolveYolo(value) {
|
|
|
5110
5127
|
throw new Error("yolo must be true or false");
|
|
5111
5128
|
}
|
|
5112
5129
|
|
|
5113
|
-
|
|
5130
|
+
/** Creation chooses a declared source, never acquisition/activation or a made-up
|
|
5131
|
+
* future release. Existing definitions (including deliberate removal) are kept. */
|
|
5132
|
+
function defaultOatsCoreRequirement() {
|
|
5133
|
+
const mapping = officialCapabilityPackage("oats.core");
|
|
5134
|
+
const entry = mapping.available && mapping.migratedCapability === "oats.core" && officialPackageCatalog()[mapping.package];
|
|
5135
|
+
if (entry && typeof entry.url === "string" && typeof entry.ref === "string" && entry.ref) {
|
|
5136
|
+
const parsed = parsePortableSource(`git:${entry.url}@${entry.ref}#${entry.path ?? DEFAULT_PACKAGE_PATH}`);
|
|
5137
|
+
return { requires: { capabilities: { "oats.core": { source: `${parsed.source}#${parsed.path}` } } }, notes: [] };
|
|
5138
|
+
}
|
|
5139
|
+
return { requires: undefined, notes: [{ code: "needs-configuration", message: "oats.core has no published revision in the official package catalog; no source was invented. Add its explicit requirement after the catalog entry is available, or use --no-oats-core to opt out at creation." }] };
|
|
5140
|
+
}
|
|
5141
|
+
|
|
5142
|
+
export function writeSoul(root, { name, kind, repo, work, runtime, model, yolo, description, type, instructions, oatsCore = true }) {
|
|
5114
5143
|
yolo = resolveYolo(yolo);
|
|
5144
|
+
if (typeof oatsCore !== "boolean") throw oatsError("E_BAD_ARGS", "oatsCore must be a boolean");
|
|
5115
5145
|
const agentDir = agentDirOf(root, name, kind);
|
|
5116
|
-
const soulDir = soulOf(agentDir);
|
|
5146
|
+
const soulDir = soulOf(agentDir), soulFile = join(soulDir, "soul.yaml");
|
|
5147
|
+
const { requires, notes } = existsSync(soulFile)
|
|
5148
|
+
? { requires: soulRequirements(soulDir), notes: [] }
|
|
5149
|
+
: oatsCore ? defaultOatsCoreRequirement() : { requires: undefined, notes: [] };
|
|
5117
5150
|
mkdirSync(soulDir, { recursive: true });
|
|
5118
5151
|
mkdirSync(join(agentDir, "instances"), { recursive: true });
|
|
5119
|
-
writeFileSync(
|
|
5152
|
+
writeFileSync(soulFile, yamlFlat({
|
|
5120
5153
|
name, kind, description, type, repo, work: work || "checkout", runtime: runtime || "pi", model, yolo,
|
|
5121
|
-
}));
|
|
5154
|
+
}) + (requires === undefined ? "" : `requires: ${JSON.stringify(requires)}\n`));
|
|
5122
5155
|
const agentsMd = join(soulDir, "AGENTS.md");
|
|
5123
5156
|
if (instructions !== undefined || !existsSync(agentsMd)) {
|
|
5124
5157
|
writeFileSync(agentsMd, instructions ?? defaultSoulAgentsMd(name, description));
|
|
@@ -5132,7 +5165,7 @@ export function writeSoul(root, { name, kind, repo, work, runtime, model, yolo,
|
|
|
5132
5165
|
home: soulDir, instance: name, agentName: name, soulDir,
|
|
5133
5166
|
contextDir: ctx, workspaceDir: workspaceOf(root), rootDir: root, resolved,
|
|
5134
5167
|
});
|
|
5135
|
-
return { agentDir, soulDir };
|
|
5168
|
+
return { agentDir, soulDir, ...(notes.length ? { notes } : {}) };
|
|
5136
5169
|
}
|
|
5137
5170
|
function defaultSoulAgentsMd(name, description) {
|
|
5138
5171
|
return `# ${name}
|
|
@@ -5154,8 +5187,8 @@ export function createAgent(root, o) {
|
|
|
5154
5187
|
// kind: "local" → a FULL soul (memory, skills, instances) under the scope's
|
|
5155
5188
|
// local-agents/ — uncommitted by contract; otherwise a committed persistent soul.
|
|
5156
5189
|
const kind = o.local || o.kind === "local" ? "local" : "persistent";
|
|
5157
|
-
const { agentDir } = writeSoul(root, { ...o, name, kind });
|
|
5158
|
-
return { agent: name, kind, soul: soulOf(agentDir) };
|
|
5190
|
+
const { agentDir, notes } = writeSoul(root, { ...o, name, kind });
|
|
5191
|
+
return { agent: name, kind, soul: soulOf(agentDir), ...(notes ? { notes } : {}) };
|
|
5159
5192
|
}
|
|
5160
5193
|
|
|
5161
5194
|
/** Upsert a local agent soul (from raw instructions or a Claude-style def file).
|
|
@@ -5182,13 +5215,13 @@ export function upsertLocalAgent(root, o) {
|
|
|
5182
5215
|
const existing = findAgent(root, name);
|
|
5183
5216
|
if (existing && existing.kind !== "local") throw new Error(`"${name}" is a persistent agent — spawn it instead`);
|
|
5184
5217
|
if (!existing && instructions === undefined) throw new Error(`local agent "${name}" needs instructions (none on disk yet)`);
|
|
5185
|
-
writeSoul(root, {
|
|
5186
|
-
name, kind: "local",
|
|
5218
|
+
const { notes } = writeSoul(root, {
|
|
5219
|
+
name, kind: "local", oatsCore: o.oatsCore,
|
|
5187
5220
|
repo: repo ?? existing?.repo, work: work ?? existing?.work,
|
|
5188
5221
|
runtime: runtime ?? existing?.runtime, model: model ?? existing?.model, yolo: yolo ?? existing?.yolo,
|
|
5189
5222
|
description: description ?? existing?.description, instructions,
|
|
5190
5223
|
});
|
|
5191
|
-
return findAgent(root, name);
|
|
5224
|
+
return { ...findAgent(root, name), ...(notes ? { notes } : {}) };
|
|
5192
5225
|
}
|
|
5193
5226
|
/** Back-compat alias: older installed capabilities (oats-okf ≤1.3.x) call this. */
|
|
5194
5227
|
export const upsertTmpAgent = upsertLocalAgent;
|
|
@@ -6136,7 +6169,7 @@ export function spawnInstance(root, agent, o = {}) {
|
|
|
6136
6169
|
symlinkSync("AGENTS.md", join(home, "CLAUDE.md"));
|
|
6137
6170
|
|
|
6138
6171
|
// Runtime-neutral exact skill materialization. No harness receives ambient workspace/package skills.
|
|
6139
|
-
const sources =
|
|
6172
|
+
const sources = legacyOperationalSkills(soulDir);
|
|
6140
6173
|
const soulSkills = join(soulDir, "skills");
|
|
6141
6174
|
if (existsSync(soulSkills)) sources.push({ id: "soul", path: soulSkills });
|
|
6142
6175
|
for (const cap of resolvedCfg.capabilities) for (const path of cap.skills || []) sources.push({ id: cap.id, path });
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** Execute only an approved retained provider command. Preparation does not need
|
|
2
2
|
* a fabricated complete resolution merely to obtain its binding. */
|
|
3
3
|
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { realpathSync } from 'node:fs';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
4
6
|
import { canonicalJson } from './portable-values.mjs';
|
|
5
7
|
import { objectAt } from './portable-shape.mjs';
|
|
6
8
|
import { validateArtifactSet } from './resolution-shape.mjs';
|
|
@@ -12,6 +14,9 @@ import { validateBindingInterface } from './provider-binding.mjs';
|
|
|
12
14
|
import { BINDING_LIMITS, validateBindingRequest, decodeBindingResponse } from './provider-binding-wire.mjs';
|
|
13
15
|
import { oatsError } from './errors.mjs';
|
|
14
16
|
|
|
17
|
+
// Same kernel-owned CLI locator as lifecycle hooks; never caller env or PATH.
|
|
18
|
+
const CLI_BIN=fileURLToPath(new URL('../bin/oats.mjs',import.meta.url));
|
|
19
|
+
|
|
15
20
|
export function invokeProviderBinding(options,codecs) {
|
|
16
21
|
canonicalJson(options);
|
|
17
22
|
objectAt(options,['deployment','artifacts','capability','phase','settings','input','timeoutMs'],['deployment','artifacts','capability','phase','settings','input']);
|
|
@@ -46,7 +51,7 @@ export function invokeProviderBinding(options,codecs) {
|
|
|
46
51
|
const [script,...args]=spec.trim().split(/\s+/),file=codecs.executable(manifest,script);
|
|
47
52
|
if (!file) throw oatsError('resource-not-found','provider codec executable is unavailable');
|
|
48
53
|
const environment=Object.fromEntries(Object.entries(process.env).filter(([key])=>! /^(OATS_|OAS_|PI_)/.test(key)));
|
|
49
|
-
Object.assign(environment,{OATS_CAPABILITY:capability,OATS_CAPABILITY_ROOT:root,OATS_SETTINGS:canonicalJson(settings,BINDING_LIMITS)});
|
|
54
|
+
Object.assign(environment,{OATS_CAPABILITY:capability,OATS_CAPABILITY_ROOT:root,OATS_SETTINGS:canonicalJson(settings,BINDING_LIMITS),OATS_CLI_BIN:realpathSync(CLI_BIN)});
|
|
50
55
|
let result;
|
|
51
56
|
try {
|
|
52
57
|
result=spawnSync(process.execPath,[file,...args],{cwd:root,env:environment,input:canonicalJson(request,BINDING_LIMITS),
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/** Read the setup edition as data for a CLASSIC local bootstrap copy.
|
|
2
|
+
* No provider code, workspace activation, enrollment or captured identity. */
|
|
3
|
+
import { lstatSync, mkdtempSync, readFileSync, readdirSync, readlinkSync, realpathSync, rmSync } from 'node:fs';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { parsePortableSoul } from './portable-soul.mjs';
|
|
8
|
+
import { parseRepositorySource, parsePortableSource } from './source-spec.mjs';
|
|
9
|
+
import { createRepositoryTransaction } from './repository-observation.mjs';
|
|
10
|
+
import { createWorkspaceDiscovery } from './workspace-discovery.mjs';
|
|
11
|
+
import { packageIntegrity } from './core.mjs';
|
|
12
|
+
import { oatsError } from './errors.mjs';
|
|
13
|
+
|
|
14
|
+
export const SETUP_EXPERT = 'oats-setup-expert';
|
|
15
|
+
export const SETUP_CAPABILITIES = Object.freeze(['oats.core', 'oats.setup']);
|
|
16
|
+
const EXPORT = `souls/${SETUP_EXPERT}`;
|
|
17
|
+
function validateEdition(bytes) {
|
|
18
|
+
const { declaration: soul } = parsePortableSoul(bytes);
|
|
19
|
+
const required = soul.requires || {}, caps = required.capabilities || {};
|
|
20
|
+
if (soul.name !== SETUP_EXPERT || soul.work !== 'directory'
|
|
21
|
+
|| Object.keys(required).some(key => key !== 'capabilities')
|
|
22
|
+
|| Object.keys(caps).length !== 2 || SETUP_CAPABILITIES.some(id => caps[id]?.source !== 'repo:oats-package' || Object.keys(caps[id]).some(key => key !== 'source'))
|
|
23
|
+
|| ['knowledge', 'messaging', 'tasks'].some(slot => soul.defaults?.[slot] !== 'none')
|
|
24
|
+
|| Object.keys(soul.defaults || {}).some(key => !['knowledge', 'messaging', 'tasks'].includes(key))
|
|
25
|
+
|| soul.knowledge || soul.teams?.length || soul.resources?.length || soul.yolo === true || soul.backend || soul['launch-config']) {
|
|
26
|
+
throw oatsError('needs-configuration', 'classic setup bootstrap needs the provider-independent directory edition with only oats.core/oats.setup; use explicit portable preparation for other requirements');
|
|
27
|
+
}
|
|
28
|
+
return soul;
|
|
29
|
+
}
|
|
30
|
+
function repositoryRequest(source) {
|
|
31
|
+
if (typeof source !== 'string' || source.includes('#')) throw oatsError('invalid-source', '--workspace needs a Git repository source, optionally @revision, without a package fragment');
|
|
32
|
+
try { return { source: parseRepositorySource(source).normalized }; }
|
|
33
|
+
catch {
|
|
34
|
+
const parsed = parsePortableSource(source);
|
|
35
|
+
if (parsed.kind !== 'git') throw oatsError('invalid-source', '--workspace needs an explicit Git repository source');
|
|
36
|
+
return { source: `git:${parsed.url}`, revision: parsed.selector };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function loadSetupExpertEdition(workspace, repositoryOptions = {}) {
|
|
41
|
+
if (workspace === undefined) {
|
|
42
|
+
const root = fileURLToPath(new URL(`../${EXPORT}/`, import.meta.url));
|
|
43
|
+
return { declaration: validateEdition(readFileSync(join(root, 'soul.yaml'))), instructions: readFileSync(join(root, 'AGENTS.md'), 'utf8'),
|
|
44
|
+
source: { kind: 'packaged-definition', captured: false }, packageIntegrity: null };
|
|
45
|
+
}
|
|
46
|
+
const request = repositoryRequest(workspace), scratch = realpathSync(mkdtempSync(join(tmpdir(), 'oats-setup-source-'))), owned = lstatSync(scratch);
|
|
47
|
+
let transaction;
|
|
48
|
+
try {
|
|
49
|
+
transaction = createRepositoryTransaction({ ...repositoryOptions, directory: scratch, accessContextKey: 'explicit-setup-source' });
|
|
50
|
+
const discovery = createWorkspaceDiscovery(transaction), origin = { kind: 'operator', document: { kind: 'operator', id: 'oats-onboard' }, pointer: '/workspace' };
|
|
51
|
+
const observed = transaction.observe(request.source, { ...request, origin });
|
|
52
|
+
const workspaceDoc = transaction.readFile(observed, 'oats-workspace.yaml', { optional: true });
|
|
53
|
+
const view = workspaceDoc ? discovery.readWorkspace({ ...request, origin }) : null;
|
|
54
|
+
const reference = view?.parsed.imports.find(item => item.alias === SETUP_EXPERT)
|
|
55
|
+
?? { source: request.source, revision: observed.source.commit, soul: EXPORT, alias: SETUP_EXPERT };
|
|
56
|
+
// A selected workspace import never falls back if its exact source fails.
|
|
57
|
+
const imported = discovery.importSoul(reference, { origin });
|
|
58
|
+
if (reference.adoption) throw oatsError('needs-configuration', 'classic setup copies an edition only; provider adoption values require the portable preparation path');
|
|
59
|
+
const declaration = validateEdition(transaction.readFile(imported.observation, imported.definition).bytes);
|
|
60
|
+
const projection = join(scratch, 'edition');
|
|
61
|
+
transaction.materialize(imported.observation, imported.roots, projection);
|
|
62
|
+
const soulRoot = join(projection, dirname(imported.definition)), body = join(soulRoot, 'AGENTS.md'), alias = join(soulRoot, 'CLAUDE.md');
|
|
63
|
+
if (!lstatSync(body).isFile() || !lstatSync(alias).isSymbolicLink() || readlinkSync(alias) !== 'AGENTS.md'
|
|
64
|
+
|| readdirSync(soulRoot).some(name => !['soul.yaml', 'AGENTS.md', 'CLAUDE.md'].includes(name))) {
|
|
65
|
+
throw oatsError('source-incomplete', 'classic setup edition must have canonical AGENTS.md/CLAUDE.md and no omitted private skill or knowledge trees');
|
|
66
|
+
}
|
|
67
|
+
return { declaration, instructions: readFileSync(body, 'utf8'), packageIntegrity: packageIntegrity(join(projection, 'oats-package')),
|
|
68
|
+
source: { kind: 'exported-edition-copy', source: imported.reference.source, revision: imported.observation.source.commit,
|
|
69
|
+
path: imported.reference.soul, workspaceRevision: view?.source.commit ?? null, captured: false } };
|
|
70
|
+
} finally {
|
|
71
|
+
transaction?.close();
|
|
72
|
+
const current = lstatSync(scratch);
|
|
73
|
+
if (!current.isDirectory() || current.dev !== owned.dev || current.ino !== owned.ino) throw oatsError('source-unavailable', 'setup source scratch ownership changed');
|
|
74
|
+
rmSync(scratch, { recursive: true });
|
|
75
|
+
}
|
|
76
|
+
}
|
package/package-catalog.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"oats.aweb": {
|
|
10
10
|
"url": "https://github.com/awebai/oats-aweb.git",
|
|
11
|
-
"ref": "v1.
|
|
11
|
+
"ref": "v1.11.0",
|
|
12
12
|
"path": "oats-package"
|
|
13
13
|
},
|
|
14
14
|
"oats.jira": {
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"ref": "v1.0.0",
|
|
32
32
|
"path": "oats-package"
|
|
33
33
|
},
|
|
34
|
-
"oats.
|
|
34
|
+
"oats.framework": {
|
|
35
35
|
"url": "https://github.com/awebai/oats.git",
|
|
36
|
-
"ref": "
|
|
36
|
+
"ref": "oats-framework/v1.1.1",
|
|
37
37
|
"path": "oats-package"
|
|
38
38
|
}
|
|
39
39
|
},
|
|
@@ -66,6 +66,9 @@
|
|
|
66
66
|
"oas.review": {
|
|
67
67
|
"package": "oats.dev",
|
|
68
68
|
"capability": "oats.review"
|
|
69
|
-
}
|
|
69
|
+
},
|
|
70
|
+
"oats.knowledge-theory": "oats.framework",
|
|
71
|
+
"oats.core": "oats.framework",
|
|
72
|
+
"oats.setup": "oats.framework"
|
|
70
73
|
}
|
|
71
74
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awebai/oats",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.2",
|
|
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",
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
"docs/",
|
|
37
37
|
"README.md",
|
|
38
38
|
"package-catalog.json",
|
|
39
|
+
"souls/oats-setup-expert/soul.yaml",
|
|
40
|
+
"souls/oats-setup-expert/AGENTS.md",
|
|
39
41
|
"packages/record/bin/",
|
|
40
42
|
"packages/record/lib/",
|
|
41
43
|
"packages/record/docs/",
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# OATS Setup Expert
|
|
2
|
+
|
|
3
|
+
Help an operator turn an empty deployment into a deliberately configured OATS
|
|
4
|
+
workspace. Explain the next small decision, inspect the existing state, obtain
|
|
5
|
+
approval for effects, and verify the result before moving on. Do not replace
|
|
6
|
+
working deployments or turn setup into an implicit enrollment operation.
|
|
7
|
+
|
|
8
|
+
## Your supplied procedures
|
|
9
|
+
|
|
10
|
+
- Load **oats-workspace-setup** for workspace/source discovery and adoption:
|
|
11
|
+
declare, inspect, prepare, approve, scaffold and start are different steps.
|
|
12
|
+
- Load **oats-config** for version-scoped classic configuration and targeting;
|
|
13
|
+
never use its cascade to fill a missing captured input.
|
|
14
|
+
- Load **oats-packages** for official package discovery, acquisition, exact locks,
|
|
15
|
+
executable approval and updates.
|
|
16
|
+
- Load **oats-operate** for lifecycle, directory boundaries and supported CLI
|
|
17
|
+
operations; load **oats-souls** for source editions, roster and relations.
|
|
18
|
+
|
|
19
|
+
Use the procedures actually included in your composition. Do not fetch a current
|
|
20
|
+
skill or invent a command when an older installed version lacks a feature.
|
|
21
|
+
|
|
22
|
+
## Setup sequence
|
|
23
|
+
|
|
24
|
+
1. Establish the operator's intended deployment, work target and workspace/source
|
|
25
|
+
separately. Inspect existing configuration, locks and souls before proposing
|
|
26
|
+
changes. A workspace is a shared definition, not a shared live runtime.
|
|
27
|
+
2. Explain `oats-workspace.yaml` and each member's separate `oats.yaml` exports
|
|
28
|
+
and backlink. Check reciprocal observations; discovery is neither membership
|
|
29
|
+
enrollment nor capability activation. Pin imports only after a source is
|
|
30
|
+
published at a real reviewed revision; never invent a future commit or tag.
|
|
31
|
+
3. Select capabilities and their exact sources with the operator. New souls
|
|
32
|
+
declare removable `oats.core` explicitly. Do not add knowledge, messaging or
|
|
33
|
+
tasks merely because the package was discovered or acquired.
|
|
34
|
+
4. Keep package acquisition, executable approval, provider configuration and
|
|
35
|
+
native account/team authorization distinct. Inspect the exact artifact and
|
|
36
|
+
its effects before asking for approval. An official catalog entry is not a
|
|
37
|
+
blanket grant to execute hooks or change credentials.
|
|
38
|
+
5. Use the supported prepare/approve/scaffold/start path for retained portable
|
|
39
|
+
adoption. Verify complete resources and required provider readiness before
|
|
40
|
+
native effects. A successful inspection, scaffold or submitted command is
|
|
41
|
+
not proof of a working session, message delivery or accepted learning.
|
|
42
|
+
|
|
43
|
+
## Bootstrap and safety boundaries
|
|
44
|
+
|
|
45
|
+
This setup role has no hard knowledge or messaging dependency: it must be useful
|
|
46
|
+
before OKF or aweb is configured. Its defaults permit none. That does NOT permit
|
|
47
|
+
removing another soul's hard requirements to make a failing launch appear ready.
|
|
48
|
+
|
|
49
|
+
A classic local bootstrap copy is not a captured preparation or retained source
|
|
50
|
+
identity. Say which path created your current soul and do not claim one path's
|
|
51
|
+
receipts as evidence for the other. Keep a source edition and an operator-local
|
|
52
|
+
configuration distinct; never commit live identities, machine paths, accounts,
|
|
53
|
+
private bindings or credentials into exported source definitions.
|
|
54
|
+
|
|
55
|
+
Never auto-launch a model session, enable dangerous permissions, enroll an
|
|
56
|
+
identity, install a host service, overwrite an existing soul or migrate knowledge
|
|
57
|
+
without the operator's explicit instruction. Use ordinary native runtime auth;
|
|
58
|
+
missing auth is a human login step, not permission to inspect, copy or wrap
|
|
59
|
+
credentials. Preserve existing instances, pending jobs, locks and failed receipts.
|
|
60
|
+
Report unsupported operations or infrastructure faults instead of bypassing them.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
schemaVersion: 1
|
|
2
|
+
name: oats-setup-expert
|
|
3
|
+
description: Guide an operator through OATS workspace adoption and explicit capability setup.
|
|
4
|
+
work: directory
|
|
5
|
+
requires:
|
|
6
|
+
capabilities:
|
|
7
|
+
oats.core:
|
|
8
|
+
source: repo:oats-package
|
|
9
|
+
oats.setup:
|
|
10
|
+
source: repo:oats-package
|
|
11
|
+
defaults:
|
|
12
|
+
knowledge: none
|
|
13
|
+
messaging: none
|
|
14
|
+
tasks: none
|