@senpi/runtime 3.0.9-dev.feat-strategy-compos.20260716013009 → 3.0.9-dev.feat-strategy-compos.20260716233548
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/dist/cli/composer-commands.d.ts.map +1 -1
- package/dist/cli/composer-commands.js +111 -2
- package/dist/cli/composer-commands.js.map +1 -1
- package/dist/cli/validate-runtime-config.mjs +66 -0
- package/dist/composer/AUTHORING.md +224 -22
- package/dist/composer/authoring/__init__.py +11 -1
- package/dist/composer/authoring/answers.py +72 -1
- package/dist/composer/authoring/archetypes/__init__.py +6 -5
- package/dist/composer/authoring/archetypes/_common.py +193 -1
- package/dist/composer/authoring/archetypes/breakout.py +134 -0
- package/dist/composer/authoring/archetypes/skeleton.py +23 -1
- package/dist/composer/authoring/archetypes/trend_momentum.py +31 -3
- package/dist/composer/cli.py +137 -5
- package/dist/composer/compiler/compile.py +202 -13
- package/dist/composer/generated/catalog.md +36 -2
- package/dist/composer/generated/describe.md +465 -0
- package/dist/composer/generated/graph.schema.json +748 -5
- package/dist/composer/primitives/__init__.py +81 -0
- package/dist/composer/primitives/adapter.py +243 -0
- package/dist/composer/primitives/indicators.py +124 -1
- package/dist/composer/primitives/sources.py +589 -15
- package/dist/composer/primitives/stateful.py +217 -15
- package/dist/composer/registry/generate.py +11 -8
- package/dist/composer/registry/mcp-tools-snapshot.json +193 -0
- package/dist/composer/registry/mcp_closure.py +311 -0
- package/dist/composer/registry/models.py +88 -2
- package/dist/composer/registry/nodes.py +634 -10
- package/dist/composer/scaffold_path.py +118 -0
- package/dist/composer/templates/scan.py.j2 +5 -2
- package/dist/composer/validator/errors.py +36 -0
- package/dist/composer/validator/graph_checks.py +97 -2
- package/dist/composer/vendoring.py +103 -0
- package/dist/composer/verbs/__init__.py +17 -1
- package/dist/composer/verbs/_box.py +308 -0
- package/dist/composer/verbs/check.py +61 -0
- package/dist/composer/verbs/close.py +494 -0
- package/dist/composer/verbs/deploy.py +65 -9
- package/dist/composer/verbs/fund.py +498 -0
- package/dist/composer/verbs/install.py +586 -0
- package/dist/composer/verbs/runtime_validate.py +162 -2
- package/dist/composer/verbs/smoke.py +44 -25
- package/dist/composer/verbs/status.py +205 -27
- package/dist/runtime/load-runtime-config.d.ts +17 -0
- package/dist/runtime/load-runtime-config.d.ts.map +1 -1
- package/dist/runtime/load-runtime-config.js +2 -2
- package/dist/runtime/load-runtime-config.js.map +1 -1
- package/dist/skills-manager/manifest.d.ts.map +1 -1
- package/dist/skills-manager/manifest.js +0 -2
- package/dist/skills-manager/manifest.js.map +1 -1
- package/dist/skills-manager/skills-manifest.json +0 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composer-commands.d.ts","sourceRoot":"","sources":["../../src/cli/composer-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,UAAU,gBAAgB;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACvD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC5C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC9D,MAAM,CACJ,EAAE,EACE,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAC5B,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GACzD,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GACzE,gBAAgB,CAAC;CACrB;AAYD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;
|
|
1
|
+
{"version":3,"file":"composer-commands.d.ts","sourceRoot":"","sources":["../../src/cli/composer-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,UAAU,gBAAgB;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACvD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC5C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC9D,MAAM,CACJ,EAAE,EACE,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAC5B,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GACzD,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GACzE,gBAAgB,CAAC;CACrB;AAYD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAmGD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CA8QjE"}
|
|
@@ -55,6 +55,12 @@ function detectEnvError(pythonBin, root, result) {
|
|
|
55
55
|
if (mod === "composer" || mod.startsWith("composer.")) {
|
|
56
56
|
return `composer: the 'composer' package was not found under ${root} — on a claw run \`npm run build\` (copy:composer) or set COMPOSER_ROOT to your checkout root.`;
|
|
57
57
|
}
|
|
58
|
+
if (mod === "scaffold" || mod.startsWith("scaffold.")) {
|
|
59
|
+
// The scaffold harness ships WITH the runtime (copy:external-scanners), never from PyPI.
|
|
60
|
+
// Do NOT route this to the "pip install deps" hint — and warn off `pip install scaffold`
|
|
61
|
+
// (an unrelated PyPI package), the exact dead end the original dev-box run hit.
|
|
62
|
+
return `composer: the 'scaffold' harness package was not found — on a claw run \`npm run build\` (copy:external-scanners stages it into dist/scanners/external) or set COMPOSER_SCAFFOLD_DIR to the dir that CONTAINS scaffold/ (…/src/scanners/external). Do NOT \`pip install scaffold\` — that is an unrelated PyPI package.`;
|
|
63
|
+
}
|
|
58
64
|
return `composer: Python dependency '${mod}' is missing — install the composer deps: ${requirementsHint(root)}`;
|
|
59
65
|
}
|
|
60
66
|
return null;
|
|
@@ -117,7 +123,7 @@ function printErrors(errors) {
|
|
|
117
123
|
}
|
|
118
124
|
export function registerComposerCli(senpi) {
|
|
119
125
|
const composer = senpi.command("composer");
|
|
120
|
-
composer.description("Strategy Composer: new / validate / compile / check / deploy / status a strategy graph; catalog / describe nodes");
|
|
126
|
+
composer.description("Strategy Composer: new / validate / compile / check / deploy / fund / install / close / status a strategy graph; catalog / describe nodes");
|
|
121
127
|
// new / validate / compile stream Python's own (rich) human render through — teaching
|
|
122
128
|
// errors, gap reports, emitted scan.py — forwarding only the relevant flags. Thin: no
|
|
123
129
|
// TS-side interpretation; the exit code is Python's (0 ok, 2 gap report, 3 clobber-refused).
|
|
@@ -239,20 +245,123 @@ export function registerComposerCli(senpi) {
|
|
|
239
245
|
printErrors(check.errors ?? []);
|
|
240
246
|
}
|
|
241
247
|
else {
|
|
248
|
+
// Always surface the ABSOLUTE staged dir Python resolved (a relative `-o` against an
|
|
249
|
+
// unexpected cwd was "deploy exited 0 but there are no files where I looked"). UNCHANGED
|
|
250
|
+
// says plainly that nothing was rewritten so an idempotent no-op never reads as a failure.
|
|
242
251
|
const staged = (json.staged ?? {});
|
|
243
|
-
|
|
252
|
+
const dir = staged.dir ?? "(no staged dir reported)";
|
|
253
|
+
if (verdict === "UNCHANGED") {
|
|
254
|
+
console.log(`UNCHANGED: ${graph} — already staged at ${dir}, nothing rewritten (idempotent no-op).`);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
console.log(`${verdict}: ${graph} — staged to ${dir}.`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
process.exitCode = status;
|
|
261
|
+
});
|
|
262
|
+
composer
|
|
263
|
+
.command("fund <target>")
|
|
264
|
+
.description("Create + fund the strategy's wallet (MCP strategy_create_custom_strategy): preflights the balance, waits for ACTIVE, safe to re-run while funding settles")
|
|
265
|
+
.option("--budget <usd>", "Explicit USD to fund this strategy's wallet with (>= $100; never derived/split)")
|
|
266
|
+
.option("-o, --out <dir>", "Staging dir (when target is a graph file, not a staged dir)")
|
|
267
|
+
.option("--state-dir <dir>", "Base senpi-state dir (default: $SENPI_STATE_DIR or ~/.openclaw/senpi-state)")
|
|
268
|
+
.option("--json", "Print the raw Python fund verdict JSON")
|
|
269
|
+
.action(async (target, opts) => {
|
|
270
|
+
const args = ["fund", target];
|
|
271
|
+
if (opts.budget !== undefined)
|
|
272
|
+
args.push("--budget", String(opts.budget));
|
|
273
|
+
if (opts.out)
|
|
274
|
+
args.push("--out", opts.out);
|
|
275
|
+
if (opts.stateDir)
|
|
276
|
+
args.push("--state-dir", opts.stateDir);
|
|
277
|
+
// The rim owns the wall-clock: created_at is injected as an ISO string (like install's bound-at).
|
|
278
|
+
args.push("--created-at", new Date().toISOString());
|
|
279
|
+
if (opts.json)
|
|
280
|
+
args.push("--json");
|
|
281
|
+
const { status, stdout, stderr, envError } = runComposer(args);
|
|
282
|
+
if (envError) {
|
|
283
|
+
process.exitCode = 1;
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (stdout)
|
|
287
|
+
process.stdout.write(stdout);
|
|
288
|
+
if (stderr)
|
|
289
|
+
process.stderr.write(stderr);
|
|
290
|
+
process.exitCode = status;
|
|
291
|
+
});
|
|
292
|
+
composer
|
|
293
|
+
.command("install <target>")
|
|
294
|
+
.description("Bind a staged unit onto THIS box: copy to a canonical hash dir, bind --wallet (or auto-bind a funded wallet.json), run `openclaw senpi runtime create`")
|
|
295
|
+
.option("--wallet <address>", "The strategy's ACTIVE 0x… wallet to bind (omit to auto-bind a funded wallet.json)")
|
|
296
|
+
.option("-o, --out <dir>", "Staging dir (when target is a graph file, not a staged dir)")
|
|
297
|
+
.option("--state-dir <dir>", "Base senpi-state dir (default: $SENPI_STATE_DIR or ~/.openclaw/senpi-state)")
|
|
298
|
+
.option("--runtime-id <id>", "Override the derived runtime id (default: <strategy>-<hash8>)")
|
|
299
|
+
.option("--json", "Print the raw Python install verdict JSON")
|
|
300
|
+
.action(async (target, opts) => {
|
|
301
|
+
const args = ["install", target];
|
|
302
|
+
if (opts.wallet)
|
|
303
|
+
args.push("--wallet", opts.wallet);
|
|
304
|
+
if (opts.out)
|
|
305
|
+
args.push("--out", opts.out);
|
|
306
|
+
if (opts.stateDir)
|
|
307
|
+
args.push("--state-dir", opts.stateDir);
|
|
308
|
+
if (opts.runtimeId)
|
|
309
|
+
args.push("--runtime-id", opts.runtimeId);
|
|
310
|
+
// Inject the wall-clock here (the rim owns the clock; the Python core stays deterministic).
|
|
311
|
+
args.push("--bound-at", new Date().toISOString());
|
|
312
|
+
if (opts.json)
|
|
313
|
+
args.push("--json");
|
|
314
|
+
const { status, stdout, stderr, envError } = runComposer(args);
|
|
315
|
+
if (envError) {
|
|
316
|
+
process.exitCode = 1;
|
|
317
|
+
return;
|
|
244
318
|
}
|
|
319
|
+
if (stdout)
|
|
320
|
+
process.stdout.write(stdout);
|
|
321
|
+
if (stderr)
|
|
322
|
+
process.stderr.write(stderr);
|
|
323
|
+
process.exitCode = status;
|
|
324
|
+
});
|
|
325
|
+
composer
|
|
326
|
+
.command("close <target>")
|
|
327
|
+
.description("Safe teardown: stop the runtime, confirm gone, then trigger MCP strategy_close (flattens positions + returns funds). Idempotent — re-run to poll")
|
|
328
|
+
.option("--wallet <address>", "Close the strategy on this 0x… wallet directly")
|
|
329
|
+
.option("--strategy-id <id>", "Close this strategyId directly (legacy/ops-deployed strategies)")
|
|
330
|
+
.option("--state-dir <dir>", "Base senpi-state dir (default: $SENPI_STATE_DIR or ~/.openclaw/senpi-state)")
|
|
331
|
+
.option("--json", "Print the raw Python close verdict JSON")
|
|
332
|
+
.action(async (target, opts) => {
|
|
333
|
+
const args = ["close", target];
|
|
334
|
+
if (opts.wallet)
|
|
335
|
+
args.push("--wallet", opts.wallet);
|
|
336
|
+
if (opts.strategyId)
|
|
337
|
+
args.push("--strategy-id", opts.strategyId);
|
|
338
|
+
if (opts.stateDir)
|
|
339
|
+
args.push("--state-dir", opts.stateDir);
|
|
340
|
+
if (opts.json)
|
|
341
|
+
args.push("--json");
|
|
342
|
+
const { status, stdout, stderr, envError } = runComposer(args);
|
|
343
|
+
if (envError) {
|
|
344
|
+
process.exitCode = 1;
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
if (stdout)
|
|
348
|
+
process.stdout.write(stdout);
|
|
349
|
+
if (stderr)
|
|
350
|
+
process.stderr.write(stderr);
|
|
245
351
|
process.exitCode = status;
|
|
246
352
|
});
|
|
247
353
|
composer
|
|
248
354
|
.command("status <target>")
|
|
249
355
|
.description("Derived lifecycle position + the next verb to run (graph file or staging dir)")
|
|
250
356
|
.option("-o, --out <dir>", "Staging directory to check for a deployed artifact")
|
|
357
|
+
.option("--state-dir <dir>", "Base senpi-state dir — extend status down the on-box install chain")
|
|
251
358
|
.option("--json", "Print the raw Python status JSON")
|
|
252
359
|
.action(async (target, opts) => {
|
|
253
360
|
const args = ["status", target, "--json"];
|
|
254
361
|
if (opts.out)
|
|
255
362
|
args.push("--out", opts.out);
|
|
363
|
+
if (opts.stateDir)
|
|
364
|
+
args.push("--state-dir", opts.stateDir);
|
|
256
365
|
const { status, stdout, json } = runComposer(args);
|
|
257
366
|
if (opts.json || !json) {
|
|
258
367
|
process.stdout.write(stdout);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composer-commands.js","sourceRoot":"","sources":["../../src/cli/composer-commands.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"composer-commands.js","sourceRoot":"","sources":["../../src/cli/composer-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -46,10 +46,24 @@ async function main() {
|
|
|
46
46
|
|
|
47
47
|
const imp = (rel) => import(pathToFileURL(pathJoin(distDir, rel)).href);
|
|
48
48
|
let runtimeConfigSchema, parseDslPluginConfig, mapRuntimeExitToDslConfig, DslConfigValidationError;
|
|
49
|
+
// A3 (install-time parity): checks the runtime runs only when it actually boots — a
|
|
50
|
+
// runtime.yaml can pass the Zod schema + DSL preset parse yet still fail at install. Imported
|
|
51
|
+
// from dist alongside the existing three oracle objects so the same single source of truth
|
|
52
|
+
// (the runtime's own code) judges them. `validateDslPositionTracking` is Runtime.start()'s DSL
|
|
53
|
+
// wiring gate; `assertUnique*Names` + `assertActionPromptPlaceholdersResolvable` are
|
|
54
|
+
// loadRuntimeConfig's post-Zod asserts the rim otherwise skips (it avoids loadRuntimeConfig to
|
|
55
|
+
// keep structured errors). All throw plain Errors — caught below and mapped to distinct codes.
|
|
56
|
+
let validateDslPositionTracking,
|
|
57
|
+
assertActionPromptPlaceholdersResolvable,
|
|
58
|
+
assertUniqueScannerNames,
|
|
59
|
+
assertUniqueActionNames;
|
|
49
60
|
try {
|
|
50
61
|
({ runtimeConfigSchema } = await imp("runtime/runtime-schema.js"));
|
|
51
62
|
({ parseDslPluginConfig, DslConfigValidationError } = await imp("dsl/config/index.js"));
|
|
52
63
|
({ mapRuntimeExitToDslConfig } = await imp("runtime/map-exit-config.js"));
|
|
64
|
+
({ validateDslPositionTracking } = await imp("runtime/validate-dsl-position-tracking.js"));
|
|
65
|
+
({ assertActionPromptPlaceholdersResolvable } = await imp("runtime/validate-action-prompts.js"));
|
|
66
|
+
({ assertUniqueScannerNames, assertUniqueActionNames } = await imp("runtime/load-runtime-config.js"));
|
|
53
67
|
} catch (err) {
|
|
54
68
|
// Signal an ENV-absent condition distinctly so Python can skip (not RED) when dist is unbuilt.
|
|
55
69
|
process.stdout.write(
|
|
@@ -117,6 +131,58 @@ async function main() {
|
|
|
117
131
|
}
|
|
118
132
|
}
|
|
119
133
|
|
|
134
|
+
// Third oracle layer (A3): install-time parity. The above proves the config PARSES; these
|
|
135
|
+
// reproduce the checks that only fire when the runtime BOOTS, so GREEN means "will install".
|
|
136
|
+
// Each new failure class carries a distinct machine `code` the Python CMP1xx mapper keys on.
|
|
137
|
+
// Collected together (not first-throw) so the author sees every install blocker at once.
|
|
138
|
+
const installErrors = [];
|
|
139
|
+
|
|
140
|
+
// load-time asserts loadRuntimeConfig runs post-Zod (the rim skips loadRuntimeConfig to keep
|
|
141
|
+
// structured errors, so it must re-run them here). Order matches load-runtime-config.ts.
|
|
142
|
+
try {
|
|
143
|
+
assertUniqueScannerNames(cfg);
|
|
144
|
+
} catch (err) {
|
|
145
|
+
installErrors.push({ path: "scanners", message: err?.message ?? String(err), code: "DUP_SCANNER_NAME" });
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
assertUniqueActionNames(cfg);
|
|
149
|
+
} catch (err) {
|
|
150
|
+
installErrors.push({ path: "actions", message: err?.message ?? String(err), code: "DUP_ACTION_NAME" });
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
assertActionPromptPlaceholdersResolvable(cfg);
|
|
154
|
+
} catch (err) {
|
|
155
|
+
installErrors.push({ path: "actions", message: err?.message ?? String(err), code: "UNRESOLVED_PROMPT_PLACEHOLDER" });
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// DSL position-tracking wiring — the Runtime.start() gate (runtime.ts:452-457). hasDsl is
|
|
159
|
+
// derived exactly as the call site does: mapRuntimeExitToDslConfig(config.exit).dsl_preset
|
|
160
|
+
// present. The map call already succeeded in the DSL layer above whenever a dsl_preset exists;
|
|
161
|
+
// if it throws for a preset-less exit block, hasDsl is false (the gate is a no-op) — that class
|
|
162
|
+
// of error is surfaced by the schema/DSL layers, not misreported here.
|
|
163
|
+
try {
|
|
164
|
+
let hasDsl = false;
|
|
165
|
+
try {
|
|
166
|
+
const exitConfig = mapRuntimeExitToDslConfig(cfg.exit);
|
|
167
|
+
const dp = exitConfig?.dsl_preset;
|
|
168
|
+
hasDsl = dp != null && typeof dp === "object" && !Array.isArray(dp);
|
|
169
|
+
} catch {
|
|
170
|
+
hasDsl = false;
|
|
171
|
+
}
|
|
172
|
+
validateDslPositionTracking(cfg, hasDsl);
|
|
173
|
+
} catch (err) {
|
|
174
|
+
const message = err?.message ?? String(err);
|
|
175
|
+
// The single function throws one of three messages; the action-wiring ones point at actions.
|
|
176
|
+
const path = /action/i.test(message) ? "actions" : "scanners";
|
|
177
|
+
installErrors.push({ path, message, code: "DSL_POSITION_TRACKING" });
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (installErrors.length > 0) {
|
|
181
|
+
process.stdout.write(JSON.stringify({ ok: false, errors: installErrors }) + "\n");
|
|
182
|
+
process.exit(0);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
120
186
|
process.stdout.write(JSON.stringify({ ok: true }) + "\n");
|
|
121
187
|
process.exit(0);
|
|
122
188
|
}
|
|
@@ -48,6 +48,16 @@ fixtures) or `composer/generated/` (registry-derived, do-not-edit).
|
|
|
48
48
|
mkdir -p drafts
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
**`scaffold` resolves itself — never set a manual `PYTHONPATH` for it.** `check`/`deploy` run
|
|
52
|
+
the emitted `scan.py` under the runtime's `scaffold` harness. The composer finds `scaffold`
|
|
53
|
+
automatically in BOTH layouts — a dev checkout (`src/scanners/external`) and a claw dist install
|
|
54
|
+
(`dist/scanners/external`, no `src/` segment) — so you do not export any path. If it genuinely
|
|
55
|
+
cannot be found, the `smoke` stage fails RED with a teaching error naming the fix: on a claw run
|
|
56
|
+
`npm run build` (its `copy:external-scanners` step stages the harness), or set
|
|
57
|
+
`COMPOSER_SCAFFOLD_DIR` to the dir that CONTAINS `scaffold/`. Do **not** `pip install scaffold` —
|
|
58
|
+
that is an unrelated PyPI package and will not satisfy the import (the harness ships with the
|
|
59
|
+
runtime, never from PyPI).
|
|
60
|
+
|
|
51
61
|
## 3. Verb reference
|
|
52
62
|
|
|
53
63
|
Every verb takes `--json` for machine-readable output; omit it for a human-readable
|
|
@@ -59,8 +69,11 @@ report.
|
|
|
59
69
|
| `validate` | Schema + graph-semantic teaching-error report (exit 0 iff clean). | `... python -m composer.cli validate drafts/my_strat.graph.yaml` |
|
|
60
70
|
| `check` | ONE verdict: validate + pure_fn inline tests + compile + one-tick smoke, staged so a failing stage skips the rest. | `... python -m composer.cli check drafts/my_strat.graph.yaml` |
|
|
61
71
|
| `compile` | Materialize the graph into `scan.py` on the `external_scanner` contract. | `... python -m composer.cli compile drafts/my_strat.graph.yaml -o drafts/scan.py` |
|
|
62
|
-
| `deploy` | Stage the COMPLETE standalone unit as a package tree (`strategy.yaml`, `main/runtime.yaml`, `main/scanners/scan.py`, `main/<id>.graph.yaml`, `manifest.json`, `deploy.json`); HARD-gated on a GREEN `check`. Does not install. | `... python -m composer.cli deploy drafts/my_strat.graph.yaml -o drafts/dist` |
|
|
63
|
-
| `
|
|
72
|
+
| `deploy` | Stage the COMPLETE standalone unit as a package tree (`strategy.yaml`, `main/runtime.yaml`, `main/scanners/scan.py`, `main/scanners/strategy_primitives/` — the vendored primitives snapshot — `main/<id>.graph.yaml`, `manifest.json`, `deploy.json`); HARD-gated on a GREEN `check`. Does not install. The verdict always reports the ABSOLUTE staged dir (a relative `-o` resolves under your current working dir), and a re-deploy of unchanged bytes is `UNCHANGED` — "already staged at `<abs>`, nothing rewritten". | `... python -m composer.cli deploy drafts/my_strat.graph.yaml -o drafts/dist` |
|
|
73
|
+
| `fund` | Create + fund the strategy's ONE wallet via MCP `strategy_create_custom_strategy`. `--budget <usd>` is REQUIRED and EXPLICIT (≥ $100) — agree it with the user; it is NEVER derived or split. Preflights the visible balance (free Hyperliquid + EVM USDC), creates, records `wallet.json` BEFORE polling, then polls briefly to ACTIVE. Idempotent + safe to re-run while funds settle (re-run IS the poll): existing ACTIVE wallet → `FUNDED` no-op; still initializing → `PENDING`; stale → CMP231. Short balance → CMP232 (states the shortfall + the bridged-funds visibility lag). Teaching errors CMP230-233 (+ CMP223 for missing creds). | `... python -m composer.cli fund drafts/dist/my_strat --budget 250` |
|
|
74
|
+
| `install` | Bind a staged unit onto THIS box: preflight (manifest verify + GREEN oracle verdict) → copy to a content-addressed immutable dir `<senpi-state>/strategies/<id>/<hash8>/` (temp+verify+atomic-rename) → bind the wallet into the COPIED `runtime.yaml` (staged source stays pristine) → invoke the frozen `openclaw senpi runtime create -p …` consumer. Pass `--wallet 0x…` explicitly, OR omit it to AUTO-BIND the funded `wallet.json` from `composer fund` (only if MCP confirms the strategy is ACTIVE; explicit `--wallet` always wins). Failures map to teaching errors (CMP200-219, + CMP206 when there is no ACTIVE wallet to auto-bind). Resumable-by-artifact. | `... python -m composer.cli fund drafts/dist/my_strat --budget 250` then `... install drafts/dist/my_strat` |
|
|
75
|
+
| `close` | SAFE TEARDOWN of a running strategy: STOP the runtime first (`openclaw senpi runtime delete`), CONFIRM it is gone, and only THEN trigger MCP `strategy_close` (flattens all positions, returns funds). Idempotent — re-running IS the poll to `CLOSED`. Target is a strategy name / canonical hash dir / runtime id / `0x…` wallet / strategyId; on-box artifacts resolve first, else legacy `strategy_list` attribution (skillName / strategyId). Failures map to teaching errors (CMP220-225). | `... python -m composer.cli close my_strat --state-dir ~/.openclaw/senpi-state` |
|
|
76
|
+
| `status` | Derives your lifecycle position (`absent` / `invalid` / `valid_undeployed` / `deployed_stale` / `deployed_current`) from the file + check + staged manifest, and names the next verb. Pass `--state-dir` to EXTEND the chain onto a box: `installable` → `installed_unregistered` → `installed_stopped` → `installed_running`, distinguishing which hash is installed/running vs merely a prior landed version. Functional liveness (scan() has actually ticked) is reported honestly as NOT-checked — `runtime list` only proves the process is up. No journal — the file is the state. | `... python -m composer.cli status drafts/my_strat.graph.yaml -o drafts/dist --state-dir ~/.openclaw/senpi-state` |
|
|
64
77
|
| `catalog` | The progressive-disclosure node index (names + one-liners + param summary) — level 1. Reference it; don't inline the whole thing into a prompt. | `... python -m composer.cli catalog` |
|
|
65
78
|
| `describe` | Full ports/params/example/cost for ONE node — level 2, on-demand deep-dive. | `... python -m composer.cli describe candles_fetch` |
|
|
66
79
|
|
|
@@ -76,17 +89,17 @@ interprets it) — plus any `requires:` capabilities. Full field definitions liv
|
|
|
76
89
|
`composer/authoring/answers.py`; the shape:
|
|
77
90
|
|
|
78
91
|
```yaml
|
|
79
|
-
archetype: trend_momentum # trend_momentum | thesis_fund | classifier
|
|
92
|
+
archetype: trend_momentum # trend_momentum | breakout | thesis_fund | classifier
|
|
80
93
|
strategy: my_strat # short id -> <id>.graph.yaml
|
|
81
94
|
universe:
|
|
82
|
-
whitelist: ["BTC", "ETH", "SOL"] # fixed asset list (trend_momentum)
|
|
95
|
+
whitelist: ["BTC", "ETH", "SOL"] # fixed asset list (trend_momentum / breakout)
|
|
83
96
|
long_basket: [] # thesis_fund LONG leg (use instead of whitelist)
|
|
84
97
|
short_basket: [] # thesis_fund SHORT leg
|
|
85
|
-
discover: false # classifier: derive the universe from the live board
|
|
86
|
-
dex: "" #
|
|
87
|
-
name_prefix: "" #
|
|
88
|
-
max_leverage_cap: 5.0 #
|
|
89
|
-
min_day_volume: 0.0 #
|
|
98
|
+
discover: false # classifier / breakout: derive the universe from the live board
|
|
99
|
+
dex: "" # discovery: venue filter
|
|
100
|
+
name_prefix: "" # discovery: instrument name prefix
|
|
101
|
+
max_leverage_cap: 5.0 # discovery: leverage ceiling
|
|
102
|
+
min_day_volume: 0.0 # discovery: daily-volume floor
|
|
90
103
|
intervals: ["4h"] # candle intervals, e.g. ["1h", "4h"]
|
|
91
104
|
max_positions: 1 # 1 = single best; >1 = rank a pool, cap to open slots
|
|
92
105
|
ttl_seconds: 240 # signal-dedup memory window
|
|
@@ -106,17 +119,62 @@ edge: >
|
|
|
106
119
|
This is carried verbatim into the graph; nothing parses it, so be as specific as you want.
|
|
107
120
|
requires: [] # [{name, kind, need}] — a capability that may not exist yet;
|
|
108
121
|
# a name the registry lacks becomes a gap report, nothing written
|
|
122
|
+
# --- OPTIONAL expressiveness (omit both for the archetype's working defaults) ---
|
|
123
|
+
indicators: # ADD registry indicator nodes and wire them into the scorer,
|
|
124
|
+
# so they become addressable by id from `scoring` below.
|
|
125
|
+
- id: fresh_raw # the node's graph id (a feature key = SOURCE NODE ID)
|
|
126
|
+
node: recent_high_bars_ago # any registry indicator (see `composer catalog`)
|
|
127
|
+
with: { window: 24, interval: "1h" } # the node's params
|
|
128
|
+
# port: bars_ago # optional: which output feeds the scorer (default: the node's sole output)
|
|
129
|
+
- id: fresh # a THRESHOLDED gate over the raw feature above (C1b)
|
|
130
|
+
node: threshold_gate # compare a per-asset feature vs a threshold -> 1.0/0.0
|
|
131
|
+
with: { op: lte, value: 5 } # op is lt|lte|gt|gte; here: bars_ago <= 5 means "fresh"
|
|
132
|
+
source: fresh_raw # CHAIN the input off fresh_raw's output (not candles)
|
|
133
|
+
scoring: # RE-SELECT the scorer's hard-vs-weighted split over the feature
|
|
134
|
+
# nodes (built-in + any `indicators` above). Each field omitted
|
|
135
|
+
# -> keep the archetype default; set -> override it.
|
|
136
|
+
required_gates: ["brk", "fresh", "vol", "lean"] # feature ids that must ALL pass (hard gates)
|
|
137
|
+
weights: { mom: 2.0, vol: 1.0, lean: 0.05 } # feature id -> weighted-sum weight
|
|
138
|
+
min_score: 0 # minimum score to emit
|
|
109
139
|
```
|
|
110
140
|
|
|
111
141
|
**Universe modes**: `whitelist` is a fixed list you already know (trend_momentum,
|
|
112
|
-
trend_conviction shapes). `long_basket`/`short_basket` are the two legs of a
|
|
113
|
-
basket (thesis_fund — a relative-value long/short). `discover: true` (+ `dex`,
|
|
142
|
+
breakout, trend_conviction shapes). `long_basket`/`short_basket` are the two legs of a
|
|
143
|
+
fixed macro basket (thesis_fund — a relative-value long/short). `discover: true` (+ `dex`,
|
|
114
144
|
`name_prefix`, `max_leverage_cap`, `min_day_volume`) derives the tradeable set each tick
|
|
115
|
-
from the live instrument board by a signature instead of a fixed list (classifier
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
145
|
+
from the live instrument board by a signature instead of a fixed list (classifier and
|
|
146
|
+
breakout). `trend_momentum` is fixed-universe only — a `discover: true` answer is rejected
|
|
147
|
+
with a teaching error pointing at `breakout` / `classifier` (it never silently emits an
|
|
148
|
+
empty universe).
|
|
149
|
+
|
|
150
|
+
**Archetypes**: `trend_momentum` (fixed universe → indicators → hard-gates + weighted-sum
|
|
151
|
+
scorer), `breakout` (a directional range-break as the hard gate, fixed basket OR discovered
|
|
152
|
+
universe — the hawk shape), `classifier` (a pure_fn direction classifier on a discovered or
|
|
153
|
+
fixed universe), `thesis_fund` (fixed long/short basket, direction fixed per leg). An
|
|
154
|
+
`archetype` the composer doesn't recognize falls back to the **off-map skeleton** — still a
|
|
155
|
+
valid, generated starting graph, just minimal; expect to do more hand-editing from there.
|
|
156
|
+
|
|
157
|
+
**Expressiveness (`scoring` / `indicators`)**: both are OPTIONAL and default to the
|
|
158
|
+
archetype's built-in scorer. `scoring` re-selects which feature nodes are HARD gates
|
|
159
|
+
(`required_gates`) versus weighted contributors (`weights`) and the score floor
|
|
160
|
+
(`min_score`), addressing feature nodes by their SOURCE NODE ID. `indicators` adds
|
|
161
|
+
registry indicator nodes (e.g. `breakout_detect` with a `window`) and wires them into the
|
|
162
|
+
scorer so they become addressable from `scoring`. A `scoring` name that matches no feature
|
|
163
|
+
node, or an `indicators` node the registry lacks, is a loud generation error — never a
|
|
164
|
+
silent drop. This is how, e.g., the `breakout` archetype expresses a four-hard-gate
|
|
165
|
+
discovery variant without any hand editing.
|
|
166
|
+
|
|
167
|
+
**Thresholded gates (`threshold_gate` + `source`)**: a hard gate must be TRUTHY, so a raw
|
|
168
|
+
numeric feature (e.g. `recent_high_bars_ago`, whose output is bars-since-the-high) can't be
|
|
169
|
+
gated directly — 0 (a high set this bar) reads falsy, a stale 40 reads truthy, exactly
|
|
170
|
+
inverted. Add a `threshold_gate` indicator (`op` one of `lt|lte|gt|gte`, `value` the
|
|
171
|
+
threshold) and CHAIN it off the raw feature with `source:` — its input then reads that node's
|
|
172
|
+
output instead of candles, emitting a real `1.0`/`0.0` gate. So a "fresh entry within 5 bars"
|
|
173
|
+
gate is `fresh = threshold_gate(op: lte, value: 5, source: fresh_raw)` over `fresh_raw =
|
|
174
|
+
recent_high_bars_ago(...)`; a "don't chase a runaway" filter is `threshold_gate(op: lt, value:
|
|
175
|
+
15, source: own_ret)` over an `own_return_24h` feature. `source` names an EARLIER `indicators`
|
|
176
|
+
entry or a built-in feature node of the archetype; an unknown source, or one whose output
|
|
177
|
+
type doesn't match the consumer's input, is a loud generation error.
|
|
120
178
|
|
|
121
179
|
Get a blank skeleton for any archetype with `composer describe`-adjacent tooling, or just
|
|
122
180
|
copy the block above and strip fields you don't need — every field has a sane default via
|
|
@@ -133,9 +191,29 @@ edit rights over the whole graph: add/remove nodes, rewire edges, retune any par
|
|
|
133
191
|
Two ways to express bespoke logic:
|
|
134
192
|
|
|
135
193
|
- **Registry nodes** (`node: <name>`, see `catalog`) — parameterized, pre-built pipeline
|
|
136
|
-
steps: sources, indicators, filters, scorers, rankers, the emitter, and
|
|
137
|
-
`ttl_dedup_state`
|
|
138
|
-
|
|
194
|
+
steps: sources, indicators, filters, scorers, rankers, the emitter, and three stateful
|
|
195
|
+
nodes (`ttl_dedup_state` for signal dedup; `snapshot_diff_state` for a bounded rolling
|
|
196
|
+
per-key growth ledger; `cohort_cache_state` to pin an expensive fetch across ticks). Wire
|
|
197
|
+
per-asset features into a scorer's `features` input to MERGE them (keyed by producing node
|
|
198
|
+
id). The cohort/cross-trader vocabulary (the whalehunter thesis) is now expressible end to
|
|
199
|
+
end: `top_traders_fetch` → `cohort_cache_state` → `trader_states_fetch` → `aggregate_bias`
|
|
200
|
+
(the one sanctioned fn→primitive promotion: cross-trader net/gross bias per coin) +
|
|
201
|
+
`snapshot_diff_state` → a bespoke cohort-scoring `pure_fn` → emit. The **world-coverage sources** span the
|
|
202
|
+
whole scanner-usable Senpi MCP read surface (proven fully-mapped by the closure check, see
|
|
203
|
+
below): market signals (funding regime/history, cross-asset flows, prices, momentum events),
|
|
204
|
+
trader intelligence (top-traders + batch trader-state, the fast 4h smart-money leaderboard
|
|
205
|
+
`leaderboard_top_fetch` and its single-trader companion `leaderboard_trader_fetch`, leaderboard
|
|
206
|
+
trader positions, copy-strategy ranking `top_strategies_fetch`, the Arena leaderboard), and
|
|
207
|
+
own-account reads (order/PnL/clearinghouse/history, banked realized-PnL on open positions).
|
|
208
|
+
They emit `record_list` outputs — ordered lists of typed dict records — and, for
|
|
209
|
+
`funding_regime_fetch`, a `label` output (a market-wide categorical string like `LONG_CROWDED`).
|
|
210
|
+
Neither type is asset-keyed: their intended consumer is a `kind: pure_fn` node that declares a
|
|
211
|
+
`record_list`/`label` input and reads the fields itself (e.g. project addresses out of
|
|
212
|
+
`top_traders_fetch.traders` and wire that record_list straight into `trader_states_fetch.traders`
|
|
213
|
+
to pull the cohort's live books; or project `{wallet_address, coin}` pairs into
|
|
214
|
+
`open_positions_realized_pnl_fetch.positions`). Prefer `leaderboard_top_fetch` for CURRENT-
|
|
215
|
+
momentum cohorts (transient 4h delta-PnL) and `top_traders_fetch` for CONSISTENT-performer
|
|
216
|
+
cohorts (multi-window track record) — the two are deliberately different reads.
|
|
139
217
|
- **`kind: pure_fn` nodes** — how you write bespoke scoring/classification math the
|
|
140
218
|
registry vocabulary can't express (e.g. the cross-feature conviction waterfall in
|
|
141
219
|
`composer/examples/conviction_scorer.graph.yaml`, corpus_origin: bison). Rules, statically
|
|
@@ -150,6 +228,20 @@ Two ways to express bespoke logic:
|
|
|
150
228
|
- it must `return` exactly its declared outputs;
|
|
151
229
|
- include `tests:` (inline fixture cases: `inputs:` → `expect:`) — these run as part of
|
|
152
230
|
`composer check`'s `pure_fn_tests` stage.
|
|
231
|
+
- **The escape hatch (`mcp_read` + the `raw` port)** — the LAST RESORT for a read the curated
|
|
232
|
+
source vocabulary doesn't wrap (or doesn't expose the fields you need). `mcp_read` calls a
|
|
233
|
+
named MCP tool with `args` passed verbatim and emits the unwrapped payload as the `raw` type;
|
|
234
|
+
you MUST wire that payload into a `kind: pure_fn` node — the NORMALIZER — which reads it and
|
|
235
|
+
returns TYPED outputs (with inline tests). What it's for: closing a genuine gap without
|
|
236
|
+
waiting for a registry add. What it is NOT: a way to bypass typing (a `raw` wire may feed
|
|
237
|
+
nothing but a pure_fn — CMP039), a general-purpose tool caller (READ-ONLY: the `tool` must be
|
|
238
|
+
in the committed snapshot and must not be a mutation — CMP060/CMP061), or a substitute for a
|
|
239
|
+
first-class node. **Reach for the registry/answers path FIRST** (`composer catalog` /
|
|
240
|
+
`composer describe`); use the hatch only when nothing fits, and be explicit in the `edge:`
|
|
241
|
+
about WHAT you're fetching and WHY the curated path can't express it. Never invent a tool —
|
|
242
|
+
if the read doesn't exist, it can't be faked here. `composer check` ANNOTATES every hatch use
|
|
243
|
+
(and flags when the tool already has a first-class node) so the usage stays visible; recurring
|
|
244
|
+
hatch use of the same shape is the maintainer's signal to wrap it as a real source node.
|
|
153
245
|
|
|
154
246
|
**Teaching errors are actionable, not decorative.** Every error from `validate`/`check`
|
|
155
247
|
carries a stable code (`CMPxxx`), a location (node id / port / line), what's wrong in one
|
|
@@ -210,6 +302,20 @@ what you'd wire in. Re-run `check` after each edit until GREEN.
|
|
|
210
302
|
nearest registry alternatives) and writes nothing. That's the correct outcome for
|
|
211
303
|
something not yet buildable; the fix is adding the capability to the registry, not
|
|
212
304
|
working around it in the graph.
|
|
305
|
+
- **Stateful nodes carry PRIOR-tick data, and the cohort cache does NOT skip the fetch.**
|
|
306
|
+
Every stateful node is split READ (prologue) / WRITE (epilogue): its outputs are read
|
|
307
|
+
BEFORE the pipeline runs and reflect the LAST persisted tick, while its late input is
|
|
308
|
+
recorded AFTER. Two consequences to author around: (1) `snapshot_diff_state.growth` is the
|
|
309
|
+
delta between the latest STORED snapshot and the oldest in the window — one tick behind this
|
|
310
|
+
tick's fresh input, and empty until ≥2 buckets have accumulated (a short warmup, exactly like
|
|
311
|
+
whalehunter's `requireGrowing` blocking until ~day 2). (2) `cohort_cache_state` does NOT
|
|
312
|
+
rate-limit — sources fire every tick and the compiler emits the upstream fetch
|
|
313
|
+
unconditionally (there is no conditional-fetch machinery). What it buys is COHORT STABILITY:
|
|
314
|
+
the read half serves the last-known-good cohort (pinned for `ttl_hours`, smoothing a transient
|
|
315
|
+
fetch failure, surviving process restarts via `ctx.state`), and the write half refreshes only
|
|
316
|
+
when the TTL lapses, the `version` changes, or the cache was empty. Cold start serves an empty
|
|
317
|
+
cohort for one warmup tick. State is BOUNDED by design (dedup prune, `max_snapshots` cap, one
|
|
318
|
+
cached cohort) — an unbounded fleet-box state series is a real ops hazard.
|
|
213
319
|
- **Ambiguous ideas need answers first, not invented specifics.** If a brief is missing
|
|
214
320
|
information you can't responsibly guess (which assets, long/short/both, how much risk),
|
|
215
321
|
ask the user rather than pick something plausible-sounding. Pin down the answers file,
|
|
@@ -226,8 +332,104 @@ what you'd wire in. Re-run `check` after each edit until GREEN.
|
|
|
226
332
|
a GREEN `check` (which now includes the `runtime_validate` stage — the real Zod + DSL oracle)
|
|
227
333
|
and stages a standalone strategy PACKAGE TREE, idempotent and side-effect-free:
|
|
228
334
|
`strategy.yaml` (catalog + funding manifest), `main/runtime.yaml` (the complete runtime:
|
|
229
|
-
strategy/scanners/actions/**exit**/risk), `main/scanners/scan.py`,
|
|
230
|
-
`
|
|
231
|
-
`
|
|
335
|
+
strategy/scanners/actions/**exit**/risk), `main/scanners/scan.py`,
|
|
336
|
+
`main/scanners/strategy_primitives/` (a vendored SNAPSHOT of `composer/primitives/`, a sibling
|
|
337
|
+
package of `scan.py`), `main/<id>.graph.yaml`, and `manifest.json` (hashing every artifact
|
|
338
|
+
including each vendored primitives file, with the runtime's Zod verdict). The emitted `scan.py`
|
|
339
|
+
imports `strategy_primitives`, NEVER `composer.*`, so the unit is self-contained: it runs on a
|
|
340
|
+
box that has none of the composer checkout — the scaffold puts the scanner dir on `sys.path` and
|
|
341
|
+
the vendored package resolves as a sibling of `scan.py`. The snapshot freezes the primitives at
|
|
342
|
+
deploy time (later `composer/primitives/` changes never mutate an already-staged strategy). There
|
|
343
|
+
is no host `runtime.yaml` to borrow — the staged unit is complete on its own. Install is `senpi-strategy-ops`:
|
|
232
344
|
it reads `strategy.yaml.instances[]`, mints one funded wallet per instance, and renders each
|
|
233
345
|
`runtime.yaml` onto its wallet. The composer never creates wallets, moves money, or installs.
|
|
346
|
+
- **`install` puts ONE instance of a staged unit onto a box — without touching the frozen runtime.**
|
|
347
|
+
`composer install <staged-dir> --wallet 0x…` (or a graph file plus `-o <staging-dir>`) is the box-side
|
|
348
|
+
step deploy stops short of. It (a) PREFLIGHTS — resolves the staged tree, verifies every artifact's
|
|
349
|
+
bytes against `manifest.json` (CMP201, tamper/hand-edit detection), and requires the recorded oracle
|
|
350
|
+
verdict to be GREEN (`VALID`; a `SKIPPED` verdict on an oracle-less box is allowed, `INVALID` is CMP202);
|
|
351
|
+
(b) COPIES the unit to a CONTENT-ADDRESSED, IMMUTABLE dir `<senpi-state>/strategies/<strategy>/<hash8>/`
|
|
352
|
+
— written to a temp sibling, every file re-verified against the manifest (CMP203), then atomic-renamed
|
|
353
|
+
into place, and NEVER edited after (so the frozen inline-YAML in the registry can't drift from the
|
|
354
|
+
scan.py re-read off disk on a scaffold respawn). `hash8` = the first 8 hex of a sha256 over the manifest
|
|
355
|
+
`artifacts` map, so identical staged content always maps to the same dir and a re-install is an idempotent
|
|
356
|
+
no-op; (c) BINDS the real `--wallet` for the `${..._WALLET}` placeholder in the COPIED `runtime.yaml` only
|
|
357
|
+
(the staged source stays pristine), records the binding in `install.json`, and re-runs the placeholder
|
|
358
|
+
policy — any remaining bare `${VAR}` after binding is CMP115; (d) INVOKES the FROZEN consumer,
|
|
359
|
+
`openclaw senpi runtime create -p <hashdir>/main/runtime.yaml` (PATH mode — never `--content`), behind an
|
|
360
|
+
injectable seam; (e) maps the known installRuntime failure classes (duplicate id CMP210,
|
|
361
|
+
one-runtime-per-wallet CMP211, wallet not ACTIVE CMP212, invalid YAML CMP213, entrypoint missing CMP214)
|
|
362
|
+
to teaching errors that name the exact next command. The runtime id is `<strategy>-<hash8>` (content-keyed,
|
|
363
|
+
so a duplicate is meaningful). Every step's completion is derivable from disk (staged tree / hash dir +
|
|
364
|
+
`install.json` / the box registry entry) — the verb is resumable-by-artifact, with no hidden session state.
|
|
365
|
+
The wallet is supplied by `--wallet`, or auto-bound from the `composer fund` `wallet.json` when `--wallet`
|
|
366
|
+
is omitted (see `fund`, below); the update/reinstall (delete+create) flow is OUT of scope (the sanctioned
|
|
367
|
+
teardown path is `composer close`, below).
|
|
368
|
+
- **`fund` creates + funds the wallet — inside the flow, with an EXPLICIT budget.** `composer fund
|
|
369
|
+
<staged-dir> --budget <usd>` is the funding step the composer used to hand off conversationally. `--budget`
|
|
370
|
+
is REQUIRED and EXPLICIT (≥ $100): agree it with the user and pass the exact amount. It is NEVER derived
|
|
371
|
+
from a `funding_share` nor split across wallets — that legacy ops derivation misfired on a real box
|
|
372
|
+
(it bridged in pieces and told a user with sufficient balance to top up), so this verb funds ONE wallet
|
|
373
|
+
with the ONE number you pass. Steps, resumable-by-artifact: (a) if `<senpi-state>/strategies/<strategy>/wallet.json`
|
|
374
|
+
exists (STRATEGY-level, ABOVE the `<hash8>` dirs — the wallet is the strategy's instance identity across
|
|
375
|
+
content versions), verify it via MCP `strategy_list` — ACTIVE → `FUNDED` no-op, still initializing →
|
|
376
|
+
`PENDING`, closed/gone → CMP231 (stale); (b) otherwise PREFLIGHT the visible balance via
|
|
377
|
+
`account_get_portfolio` (free Hyperliquid + free EVM USDC, summed as the backend funds a create) — short
|
|
378
|
+
of budget → CMP232 stating the current visible total, the exact shortfall, the bridged-funds VISIBILITY
|
|
379
|
+
LAG (funds moved HL→EVM can lag ~a minute; wait + re-run), and the top-up options (the composer NEVER
|
|
380
|
+
bridges); (c) sufficient → call MCP `strategy_create_custom_strategy` (`skillName` = the strategy name,
|
|
381
|
+
matching what `composer close`'s legacy discovery reads), record `wallet.json` BEFORE polling, then poll
|
|
382
|
+
briefly to ACTIVE. `strategy_create_custom_strategy` is a MONEY MUTATION: there is no `--yes` (the CLI is
|
|
383
|
+
agent-driven — the user's confirmation is conversational per the skill), but the verb prints an
|
|
384
|
+
unmistakable pre-action line (creating wallet, budget, funding source) in its result. Missing MCP creds
|
|
385
|
+
is a loud CMP223. Then `composer install` (omit `--wallet`) auto-binds the funded wallet.
|
|
386
|
+
- **`close` is the ONLY sanctioned teardown — never a raw `strategy_close`.** The invariant is
|
|
387
|
+
non-negotiable: STOP the runtime first (`openclaw senpi runtime delete <id>`), CONFIRM it is gone,
|
|
388
|
+
and ONLY THEN submit MCP `strategy_close(<strategyId>)` (which flattens ALL positions and returns
|
|
389
|
+
funds). A raw `strategy_close` with a live runtime STRANDS the runtime — it keeps trading a wallet the
|
|
390
|
+
server is tearing down. `composer close <target>` enforces this behind injectable seams: if the runtime
|
|
391
|
+
delete fails (CMP220) or the runtime is still present afterward (CMP221), `strategy_close` is WITHHELD
|
|
392
|
+
and the verb fails loud rather than strand or double-fire. It is IDEMPOTENT and SUBMIT-ONLY (no poll):
|
|
393
|
+
`strategy_close` is async, so the verb reports `CLOSING` and re-running it IS the poll — a re-run skips
|
|
394
|
+
the delete (runtime already gone) and skips the re-submit (strategy left the ACTIVE set), reporting
|
|
395
|
+
`CLOSED` once the strategy is terminal. It resolves the target from the composer's own on-box artifacts
|
|
396
|
+
first (a canonical hash dir's `install.json`, or a strategy name / runtime id under `--state-dir`), and
|
|
397
|
+
falls back to `strategy_list` attribution (skillName / strategyId + the wallet read from the strategy
|
|
398
|
+
record) so it also closes legacy ops-deployed strategies and orphan runtimes. Missing MCP creds
|
|
399
|
+
(`SENPI_API_KEY`) is a loud CMP223, not a silent skip.
|
|
400
|
+
- **`status --state-dir` is the resumable-by-artifact install chain.** With a box named, `status` walks
|
|
401
|
+
the current staged content DOWN onto the box entirely from artifacts + one read-only `runtime list`:
|
|
402
|
+
landed (canonical hash dir + `install.json`) → registered (`installed_runtimes.json`) → running. Multiple
|
|
403
|
+
hash dirs for one strategy are distinguished — which hash is installed/running vs a merely-landed prior
|
|
404
|
+
version. Liveness is reported HONESTLY: `runtime list` proves only that the process is up, so a running
|
|
405
|
+
install is annotated that functional liveness (scan() `runCount>0`, a fresh `lastRunFinishedAt`,
|
|
406
|
+
`consecutiveErrorCount==0` — see `senpi-strategy-ops/references/liveness-verification.md`) is NOT checked
|
|
407
|
+
here; run `openclaw senpi state -r <id> --json` for that. "running" ≠ "operating".
|
|
408
|
+
|
|
409
|
+
## 8. Debugging generation deterministically
|
|
410
|
+
|
|
411
|
+
Generation (`new`/`check`/`deploy`) is fully offline-reproducible: no creds, no network, no
|
|
412
|
+
wall-clock — the same answers always produce the same bytes. So any "the composer generated the
|
|
413
|
+
wrong thing" report replays exactly. The procedure (proven on the first real dev-test incident):
|
|
414
|
+
|
|
415
|
+
1. Reconstruct the user's answers file from the conversation (the graph's `metadata` block IS the
|
|
416
|
+
answers when you have the generated graph — spec-is-state).
|
|
417
|
+
2. Drive the CLI into a scratch dir: `python -m composer.cli new --archetype <a> --answers <f> -o /tmp/repro`
|
|
418
|
+
(deps: pyyaml, pydantic, jinja2, jsonschema — a throwaway venv or `uvx` is enough).
|
|
419
|
+
3. Diff the emitted graph against what the user agreed to — the delta names the lost intent.
|
|
420
|
+
4. Read the archetype's `build()` in `composer/authoring/archetypes/` for where that intent was
|
|
421
|
+
dropped (a hardcoded literal, an unread answer field, a missing archetype route).
|
|
422
|
+
|
|
423
|
+
Classify before fixing: COVERAGE (no archetype+params expresses it) · EXPRESSIVENESS (the answers
|
|
424
|
+
surface can't say it) · ROUTING (wrong archetype chosen) · INSTRUCTION (the skill never told the
|
|
425
|
+
agent to pass it). Each has a different smallest fix — and only genuinely-missing SOURCE
|
|
426
|
+
capability (no data feed in the world) is a registry gap; everything else is composer-side.
|
|
427
|
+
|
|
428
|
+
**Maintainer note (source coverage).** The source vocabulary is kept EXHAUSTIVE over the scanner-
|
|
429
|
+
usable Senpi MCP read surface, and that claim is enforced continuously by the CI closure check
|
|
430
|
+
(`composer/registry/mcp_closure.py`, offline by default). If a new server-side read tool appears,
|
|
431
|
+
CI goes red until it is either mapped by a new source node (declaring `mcp_tool="..."`) or added to
|
|
432
|
+
the allowlist with a reason. To pick up a catalog change, run
|
|
433
|
+
`MCP_SNAPSHOT_REFRESH=1 pytest python-tests/composer/test_mcp_closure.py` (fetches the live
|
|
434
|
+
unauthenticated `tools/list`, rewrites `mcp-tools-snapshot.json`, and surfaces input-schema drift),
|
|
435
|
+
then commit the refreshed snapshot. Full design in `docs/composer/design-models.md` §9.
|