mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-10 11:47:54 +02:00
feat: add gated Itô inference skill lifecycle
This commit is contained in:
@@ -202,6 +202,14 @@
|
||||
"ito-compute"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "capability:ito-inference",
|
||||
"family": "capability",
|
||||
"description": "Gated Itô inference preflight, deployment, observability, and cleanup on existing entitled clusters.",
|
||||
"modules": [
|
||||
"ito-inference"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "capability:social",
|
||||
"family": "capability",
|
||||
|
||||
@@ -634,6 +634,36 @@
|
||||
"cost": "light",
|
||||
"stability": "beta"
|
||||
},
|
||||
{
|
||||
"id": "ito-inference",
|
||||
"kind": "skills",
|
||||
"description": "Gated Itô inference eligibility, entitlement, deployment, observability, and cleanup on existing clusters.",
|
||||
"paths": [
|
||||
"skills/ito-inference"
|
||||
],
|
||||
"targets": [
|
||||
"claude",
|
||||
"claude-project",
|
||||
"cursor",
|
||||
"antigravity",
|
||||
"codex",
|
||||
"gemini",
|
||||
"opencode",
|
||||
"codebuddy",
|
||||
"joycode",
|
||||
"qwen",
|
||||
"zed",
|
||||
"hermes",
|
||||
"openclaw",
|
||||
"kimi"
|
||||
],
|
||||
"dependencies": [
|
||||
"ito-compute"
|
||||
],
|
||||
"defaultInstall": false,
|
||||
"cost": "light",
|
||||
"stability": "experimental"
|
||||
},
|
||||
{
|
||||
"id": "social-distribution",
|
||||
"kind": "skills",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
"optimization-workflows",
|
||||
"prediction-market-skills",
|
||||
"ito-compute",
|
||||
"ito-inference",
|
||||
"social-distribution",
|
||||
"media-generation",
|
||||
"orchestration",
|
||||
|
||||
@@ -224,6 +224,7 @@
|
||||
"skills/inventory-demand-planning/",
|
||||
"skills/ito-basket-compare/",
|
||||
"skills/ito-compute/",
|
||||
"skills/ito-inference/",
|
||||
"skills/ito-data-atlas-agent/",
|
||||
"skills/ito-inference/",
|
||||
"skills/ito-market-intelligence/",
|
||||
|
||||
+12
-4
@@ -10,7 +10,7 @@ const {
|
||||
getInvocationCommand,
|
||||
} = require("./lib/ito-environment");
|
||||
|
||||
const SUPPORTED_COMMANDS = Object.freeze(["login", "logout", "auth", "find", "status", "evals"]);
|
||||
const SUPPORTED_COMMANDS = Object.freeze(["login", "logout", "auth", "find", "status", "evals", "inference"]);
|
||||
const CANONICAL_REPOSITORY = "https://github.com/Ito-Markets/ito-cloud-runtime.git";
|
||||
const CANONICAL_PACKAGE_PATH = "cli/ito-compute-cli";
|
||||
const CANONICAL_ENTRY_SEGMENTS = Object.freeze([
|
||||
@@ -34,14 +34,18 @@ Usage:
|
||||
ecc ito find <all required RFQ options>
|
||||
ecc ito status
|
||||
ecc ito evals --cluster <id> --live-sixtytwo --nodes <list> --config-dir <dir>
|
||||
ecc ito <login|logout|auth|find|status|evals> --json
|
||||
ecc ito inference preflight --cluster <id> --model <owner/model> --revision <commit> --engine vllm --max-runtime-hours <hours>
|
||||
ecc ito inference deploy <same options> --confirm-cost-usd <exact preflight amount>
|
||||
ecc ito inference <status|logs> --deployment <id>
|
||||
ecc ito inference stop --deployment <id> --confirm
|
||||
ecc ito <login|logout|auth|find|status|evals|inference> --json
|
||||
|
||||
The bridge invokes the separately installed canonical Itô CLI and returns its
|
||||
real stdout, stderr, and exit code unchanged. "ecc ito login" delegates to the
|
||||
canonical CLI's device authorization. It opens the Itô verification page by default
|
||||
and persists its device token in macOS Keychain. Pass --no-browser to
|
||||
suppress that handoff. ECC itself performs no browser automation and adds no
|
||||
lock, workload, inference, or purchase path.
|
||||
lock, workload, or purchase path.
|
||||
"ecc ito auth" is validation-only and never starts device login.
|
||||
"ecc ito logout" asks the canonical CLI to revoke the current device credential
|
||||
and remove its local copy only after remote revocation is confirmed.
|
||||
@@ -52,6 +56,10 @@ Important:
|
||||
- "status" reads live RFQ and procurement status.
|
||||
- "evals" invokes only the canonical CLI's double-opt-in, pinned
|
||||
sixtytwo-cli node-qualification adapter against explicit nodes.
|
||||
- "inference preflight" is read-only; deploy and stop require the canonical
|
||||
CLI's exact cost and explicit cleanup confirmations.
|
||||
- Inference operates only on an existing active, entitled cluster. It cannot
|
||||
find, book, reserve, purchase, resize, or delete compute capacity.
|
||||
- Node qualification cannot rent, launch, recover, repair, or purchase.
|
||||
- Inventory and RFQs are not reservations; only a returned firm quote is firm.
|
||||
|
||||
@@ -164,7 +172,7 @@ function parseArgs(argv, environment = process.env) {
|
||||
const command = withoutJson.shift();
|
||||
if (!SUPPORTED_COMMANDS.includes(command)) {
|
||||
throw new Error(
|
||||
`Unsupported Itô command "${command || "(missing)"}"; ECC permits only login, logout, auth, find, status, and evals.`
|
||||
`Unsupported Itô command "${command || "(missing)"}"; ECC permits only login, logout, auth, find, status, evals, and inference.`
|
||||
);
|
||||
}
|
||||
if (command === "auth" && withoutJson.includes("--no-browser")) {
|
||||
|
||||
@@ -45,7 +45,7 @@ const ECC_ITO_CONTROL_KEYS = Object.freeze([
|
||||
"ECC_ITO_CLI_EXECUTABLE",
|
||||
"NODE_ENV",
|
||||
]);
|
||||
const ITO_RUNTIME_COMMANDS = new Set(["login", "logout", "auth", "find", "status"]);
|
||||
const ITO_RUNTIME_COMMANDS = new Set(["login", "logout", "auth", "find", "status", "inference"]);
|
||||
|
||||
function copyDefined(source, target, key) {
|
||||
if (typeof source[key] === "string") {
|
||||
@@ -97,7 +97,7 @@ function createSafeItoInvocationEnvironment(
|
||||
return createSafeItoEnvironment(source, {
|
||||
includeControls: options.includeControls === true,
|
||||
includeItoRuntime: ITO_RUNTIME_COMMANDS.has(command),
|
||||
includeItoApiKey: ["auth", "find", "status"].includes(command),
|
||||
includeItoApiKey: ["auth", "find", "status", "inference"].includes(command),
|
||||
includeItoEvals: command === "evals",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,119 +1,98 @@
|
||||
---
|
||||
name: ito-inference
|
||||
description: Inspect the availability of model serving on a completed Itô compute booking and, when the canonical backend becomes available, hand off an explicitly confirmed serving manifest. Use after ito-compute has booked GPU nodes and the user asks for an OpenAI-compatible endpoint, ito-serve, hosted Kimi, or self-hosted open-weights inference. ECC implements no serving stack of its own.
|
||||
metadata:
|
||||
origin: ECC
|
||||
status: scaffold
|
||||
aliases: ito-serve, hosted-open-weights
|
||||
description: Preflight, deploy, observe, and stop self-hosted open-weights inference on an existing eligible and entitled Itô compute cluster. Use when a user asks to deploy, host, serve, run inference, check health or logs, or tear down a Kimi or other open-weights model on Itô GPUs.
|
||||
---
|
||||
|
||||
# Itô Inference
|
||||
|
||||
`ito-inference` is the sole canonical ECC skill for inference serving on Itô
|
||||
compute. Requests naming `ito-serve` route here; do not create or install a
|
||||
second `ito-serve` skill. ECC never SSHes to nodes, downloads weights, launches
|
||||
an engine, or exposes an endpoint; it never books, reserves, or spends.
|
||||
Use only the reviewed canonical `ecc ito inference` lifecycle. This skill never
|
||||
finds, books, reserves, resizes, purchases, or deletes compute capacity. Never
|
||||
substitute SSH, systemd, a local vLLM runner, browser automation, or an invented
|
||||
API/MCP tool.
|
||||
|
||||
## Current production boundary
|
||||
## Establish intent and authority
|
||||
|
||||
Managed serving is unavailable today. The ECC bridge exposes only `login`,
|
||||
`auth`, `find`, `status`, and explicitly gated `evals`. It has no `serve` verb.
|
||||
The canonical runtime documents `inference` only as an unsupported compatibility
|
||||
probe; ECC does not invoke or depend on it. The MCP surface exposes only auth,
|
||||
find, and status. The locally enforceable guarantee is that ECC rejects `serve`
|
||||
before resolving or spawning the credential-bearing canonical client.
|
||||
Require the originating agent's completed Itô booking record: account, cluster
|
||||
id, active status, nodes, GPU topology, service start, and entitlement context.
|
||||
Collect an exact Hugging Face `owner/model`, a pinned 7–64 character hexadecimal
|
||||
revision, `vllm`, quantization (`none`, `awq`, or `gptq`), and a bounded runtime
|
||||
of 1–168 hours. Return to the originating agent for missing booking data; do not
|
||||
select another cluster.
|
||||
|
||||
Therefore stop before authentication or any command invocation. Report the
|
||||
missing capability and return to the originating agent. Never substitute a
|
||||
local runner, SSH helper, browser workflow, purchase endpoint, or any untracked
|
||||
local `ito-serve` draft.
|
||||
Deployment and teardown are separate state-changing actions. Obtain explicit
|
||||
user confirmation immediately before each. A compute booking confirmation does
|
||||
not authorize serving, and a deployment confirmation does not authorize stop.
|
||||
|
||||
## Required entitlement
|
||||
## Authenticate
|
||||
|
||||
When serving is implemented, its first gate is a server-verified completed
|
||||
booking. Harness memory, an RFQ, a quote, node IPs, or SSH access are not proof
|
||||
of entitlement. The backend must return fresh serving eligibility bound to the
|
||||
authenticated account, booking, GPU topology, region, fabric, term, and model
|
||||
policy. Expired, revoked, mismatched, incomplete, or already-released bookings
|
||||
fail closed before confirmation.
|
||||
Run `ecc ito auth --json`. If authentication is missing, run `ecc ito login`,
|
||||
present the canonical device URL/code handoff, and return control to the
|
||||
originating agent while the user completes authorization. Then retry
|
||||
`ecc ito auth --json`. Never place a key, token, or device code in chat, files,
|
||||
screenshots, or logs. Timeout, denial, or revocation is not success; repeat the
|
||||
device flow and never silently switch accounts.
|
||||
|
||||
## Future CLI and API contract
|
||||
## Preflight
|
||||
|
||||
The intended command name is `serve`; `inference` may remain only as an
|
||||
explicitly deprecated compatibility alias after the production contract lands.
|
||||
The future handoff must be equivalent to:
|
||||
Run the fresh, read-only check:
|
||||
|
||||
```sh
|
||||
ecc ito serve \
|
||||
--booking <server-verified-booking-id> \
|
||||
--manifest <absolute-reviewed-json-file> \
|
||||
--confirmation-ref <opaque-non-authorizing-reference> \
|
||||
--idempotency-key <stable-retry-key> \
|
||||
--json
|
||||
```text
|
||||
ecc ito inference preflight --cluster <cluster-id> --model <owner/model> --revision <commit> --engine vllm --quantization <none|awq|gptq> --max-runtime-hours <1-168> --json
|
||||
```
|
||||
|
||||
The reviewed manifest must identify the model revision, engine and version,
|
||||
quantization, tensor/pipeline topology, endpoint exposure policy, artifact
|
||||
checksums, storage ceiling, runtime limits, optional TTFT/TPOT objectives, and
|
||||
maximum incremental cost. No raw API key, SSH key, node password, or bearer
|
||||
token belongs in arguments, manifests, logs, MCP results, or chat.
|
||||
Proceed only when the response says the authenticated account is entitled, the
|
||||
exact cluster is active, every contracted node is present and up, service has
|
||||
started, and the model configuration is valid. Record the returned exact
|
||||
`estimated_cost_usd`. This is a conservative serving ceiling on already-booked
|
||||
capacity; it is not authority to buy capacity.
|
||||
|
||||
The client must canonicalize the manifest path, reject symlinks, open a regular
|
||||
file without following links, require appropriate ownership and restrictive
|
||||
permissions, enforce a bounded size, and hash bytes from the opened descriptor.
|
||||
That digest must exactly equal the digest bound into confirmation before any
|
||||
workload mutation. A path swap, digest mismatch, oversized file, or mutable
|
||||
unsafe file fails closed.
|
||||
## Deploy
|
||||
|
||||
The canonical API—not ECC—must own workload creation and return structured JSON
|
||||
with `ok`, `live_api_contacted`, `notice`, and either `data` or `error`. Serving
|
||||
data must include stable booking, workload, manifest, and idempotency IDs plus a
|
||||
state enum; it must not claim an endpoint is live until health and model checks
|
||||
pass. Errors must include a stable code and safe message without secrets.
|
||||
After explicit user confirmation, bind that confirmation to the exact current
|
||||
preflight amount:
|
||||
|
||||
## Confirmation and execution gates
|
||||
```text
|
||||
ecc ito inference deploy --cluster <cluster-id> --model <owner/model> --revision <commit> --engine vllm --quantization <none|awq|gptq> --max-runtime-hours <1-168> --confirm-cost-usd <exact-amount> --json
|
||||
```
|
||||
|
||||
Before workload creation, require all of the following:
|
||||
Do not round, edit, or reuse a stale amount. The canonical client supplies an
|
||||
idempotency key and rejects missing/mismatched confirmation. On timeout or an
|
||||
ambiguous response, do not deploy again blindly; query status using any returned
|
||||
deployment id and otherwise report the ambiguity for operator reconciliation.
|
||||
|
||||
1. Fresh entitlement and serving eligibility from the canonical backend.
|
||||
2. A reviewable immutable manifest and deterministic digest.
|
||||
3. A separate single-use confirmation bound to account, action, manifest, and
|
||||
cost, with a short expiry and replay protection. CLI arguments carry only an
|
||||
opaque, non-authorizing confirmation reference; the server resolves and
|
||||
consumes the bearer capability out of band.
|
||||
4. A caller-supplied idempotency key reserved atomically with the workload.
|
||||
5. Server-side fabric, capacity, model-policy, storage, and cost validation.
|
||||
## Observe
|
||||
|
||||
Authentication is identity, not workload authority. A login, API key, quote,
|
||||
or completed booking never substitutes for the serving confirmation. Inspection
|
||||
and plan generation must not create a workload. Cancel and cleanup are separate
|
||||
mutations with their own scoped confirmation and idempotency boundaries.
|
||||
Read canonical state; never infer readiness from process exit alone:
|
||||
|
||||
## Lifecycle and recovery
|
||||
```text
|
||||
ecc ito inference status --deployment <deployment-id> --json
|
||||
ecc ito inference logs --deployment <deployment-id> --limit <1-500> --json
|
||||
```
|
||||
|
||||
The production surface is incomplete until the same canonical client exposes
|
||||
tenant-scoped status, logs, metrics, cancel, and cleanup operations. Every
|
||||
operation needs bounded connect and overall timeouts, revocation-aware errors,
|
||||
and structured output. After an ambiguous transport failure, query status by
|
||||
the idempotency key before retrying; never create a second workload merely
|
||||
because the first response was lost. A revoked credential stops polling and
|
||||
returns control to the originating agent without starting login automatically.
|
||||
Claim readiness only when status reports the pinned model revision, a healthy
|
||||
deployment, and its endpoint. Redact credentials and signed endpoint material.
|
||||
Logs are bounded and read-only. A provider timeout, invalid status, or revoked
|
||||
authentication is an error, not cached success.
|
||||
|
||||
Only report `ready` after endpoint health, model identity, and canary inference
|
||||
all pass. Report intermediate and terminal failure states honestly. Cleanup must
|
||||
be observable and must not release or modify the underlying booking unless that
|
||||
separate economic action was explicitly authorized.
|
||||
## Stop and verify cleanup
|
||||
|
||||
## Proposed backend stages
|
||||
After separate explicit teardown confirmation:
|
||||
|
||||
These stages describe the future backend, not code that exists in ECC:
|
||||
```text
|
||||
ecc ito inference stop --deployment <deployment-id> --confirm --json
|
||||
ecc ito inference status --deployment <deployment-id> --json
|
||||
```
|
||||
|
||||
1. Verify entitlement, topology, fabric, and cost gates.
|
||||
2. Fetch checksum-pinned weights into backend-managed storage.
|
||||
3. Emit and validate a reviewable topology/engine plan.
|
||||
4. Launch through the provider control plane, never direct root SSH from ECC.
|
||||
5. Warm up, test health and model identity, run an SLO canary, then register the
|
||||
endpoint and redacted configuration.
|
||||
Report cleanup complete only after canonical state is `stopped` with no active
|
||||
endpoint. Stopping serving must not cancel or delete the underlying compute
|
||||
booking. If stop is ambiguous, retain `cleanup.required=true` and escalate for
|
||||
status reconciliation rather than claiming completion.
|
||||
|
||||
Until every gate and lifecycle operation above exists in the canonical runtime,
|
||||
this skill remains a fail-closed availability check and documentation handoff.
|
||||
## Structured result
|
||||
|
||||
Return one secret-free object with `status` (`PASS` or `BLOCK`), phase, account
|
||||
and cluster ids, authenticated/eligible/entitled flags, model and revision,
|
||||
estimated cost, deployment id, health, endpoint, bounded log evidence, cleanup
|
||||
required/completed, error code, and next action. Distinguish code existence,
|
||||
local test pass, merge, deployment, and observed live behavior. Use `PASS` only
|
||||
for the lifecycle stage actually observed.
|
||||
|
||||
@@ -1,130 +1,77 @@
|
||||
/**
|
||||
* Contract tests for the installable, fail-closed Itô inference handoff.
|
||||
*/
|
||||
/** Contract tests for the installable, fail-closed Itô inference skill. */
|
||||
|
||||
const assert = require("assert");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const path = require("path");
|
||||
const { spawnSync } = require("child_process");
|
||||
|
||||
const REPO_ROOT = path.join(__dirname, "..", "..");
|
||||
const ROOT = path.join(__dirname, "..", "..");
|
||||
const read = (file) => fs.readFileSync(path.join(ROOT, file), "utf8");
|
||||
const json = (file) => JSON.parse(read(file));
|
||||
const skill = read("skills/ito-inference/SKILL.md");
|
||||
|
||||
function read(relativePath) {
|
||||
return fs.readFileSync(path.join(REPO_ROOT, relativePath), "utf8");
|
||||
}
|
||||
|
||||
function readJson(relativePath) {
|
||||
return JSON.parse(read(relativePath));
|
||||
}
|
||||
|
||||
function test(name, fn) {
|
||||
try {
|
||||
fn();
|
||||
console.log(` ✓ ${name}`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.log(` ✗ ${name}`);
|
||||
console.error(` ${error.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("\n=== Testing Itô inference skill lifecycle ===\n");
|
||||
|
||||
const results = [
|
||||
test("uses the canonical serving trigger and fails closed while unavailable", () => {
|
||||
const skill = read("skills/ito-inference/SKILL.md");
|
||||
assert.match(skill, /^name: ito-inference$/m);
|
||||
assert.match(skill, /self-host|serve a model|OpenAI-compatible endpoint/i);
|
||||
assert.match(skill, /requests naming .*ito-serve/i);
|
||||
assert.match(skill, /completed booking/i);
|
||||
assert.match(skill, /never books, reserves,\s+or spends/i);
|
||||
assert.match(skill, /serving is unavailable today/i);
|
||||
assert.match(skill, /report the\s+missing capability and return/i);
|
||||
assert.match(skill, /stop before authentication/i);
|
||||
assert.match(skill, /no `serve` verb/i);
|
||||
assert.match(skill, /`inference`.*unsupported compatibility\s+probe/i);
|
||||
assert.match(skill, /never substitute a\s+local runner, SSH helper, browser workflow, purchase endpoint/i);
|
||||
assert.doesNotMatch(skill, /ssh\s+root@|serve-status\.sh/i);
|
||||
for (const gate of [
|
||||
/server-verified completed\s+booking/i,
|
||||
/fresh serving eligibility/i,
|
||||
/single-use confirmation/i,
|
||||
/account, action, manifest, and\s+cost/i,
|
||||
/idempotency/i,
|
||||
/status, logs, metrics, cancel, and cleanup/i,
|
||||
/structured JSON/i,
|
||||
/ambiguous transport/i,
|
||||
/reject symlinks/i,
|
||||
/without following links/i,
|
||||
/hash bytes from the opened descriptor/i,
|
||||
/digest must exactly equal/i,
|
||||
]) assert.match(skill, gate);
|
||||
assert.match(skill, /--confirmation-ref <opaque-non-authorizing-reference>/i);
|
||||
assert.doesNotMatch(skill, /--confirmation-token|--api-key|--access-token/i);
|
||||
}),
|
||||
test("keeps unsupported serving outside the executable bridge", () => {
|
||||
const bridge = read("scripts/ito.js");
|
||||
assert.match(bridge, /SUPPORTED_COMMANDS[^\n]+login[^\n]+auth[^\n]+find[^\n]+status[^\n]+evals/);
|
||||
assert.doesNotMatch(bridge, /SUPPORTED_COMMANDS[^\n]+serve/);
|
||||
assert.match(bridge, /Unsupported Itô command/);
|
||||
|
||||
const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), "ecc-ito-serve-reject-"));
|
||||
try {
|
||||
const canonicalDir = path.join(fixtureRoot, "cli", "ito-compute-cli", "dist", "bin");
|
||||
fs.mkdirSync(canonicalDir, { recursive: true });
|
||||
const marker = path.join(fixtureRoot, "spawned");
|
||||
const executable = path.join(canonicalDir, "ito.js");
|
||||
fs.writeFileSync(executable, `require("fs").writeFileSync(${JSON.stringify(marker)}, "spawned");\n`);
|
||||
const result = spawnSync(process.execPath, [
|
||||
path.join(REPO_ROOT, "scripts", "ecc.js"), "ito", "serve",
|
||||
"--booking", "booking_test", "--model", "model_test",
|
||||
], {
|
||||
encoding: "utf8",
|
||||
env: { ...process.env, ECC_ITO_CLI_EXECUTABLE: executable },
|
||||
});
|
||||
assert.notStrictEqual(result.status, 0);
|
||||
assert.match(result.stderr, /Unsupported Itô command "serve"/);
|
||||
assert.ok(!fs.existsSync(marker), "unsupported serve spawned the canonical child");
|
||||
} finally {
|
||||
fs.rmSync(fixtureRoot, { recursive: true, force: true });
|
||||
const tests = [
|
||||
["has trigger-rich two-field frontmatter", () => {
|
||||
const frontmatter = skill.match(/^---\n([\s\S]*?)\n---/)[1];
|
||||
const keys = [...frontmatter.matchAll(/^([a-z_-]+):/gm)].map((match) => match[1]);
|
||||
assert.deepStrictEqual(keys, ["name", "description"]);
|
||||
for (const phrase of ["deploy", "host", "serve", "run inference", "check", "tear down"]) {
|
||||
assert.match(frontmatter, new RegExp(phrase, "i"));
|
||||
}
|
||||
}),
|
||||
test("ships canonical inference through the existing opt-in compute module", () => {
|
||||
const modules = readJson("manifests/install-modules.json").modules;
|
||||
const module = modules.find((candidate) => candidate.id === "ito-compute");
|
||||
assert.ok(module, "ito-compute install module is missing");
|
||||
assert.deepStrictEqual(module.paths, [
|
||||
"skills/ito-compute",
|
||||
"skills/ito-inference",
|
||||
"skills/ito-training",
|
||||
]);
|
||||
assert.deepStrictEqual(module.dependencies, ["platform-configs"]);
|
||||
}],
|
||||
["requires originating booking, exact eligibility, and no capacity selection", () => {
|
||||
for (const pattern of [
|
||||
/originating agent/, /completed Itô booking/, /cluster id/, /active status/,
|
||||
/entitlement/, /do not\s+select another cluster/, /never\s+finds, books, reserves/,
|
||||
]) assert.match(skill, pattern);
|
||||
}],
|
||||
["documents device login return and revocation recovery without secrets", () => {
|
||||
for (const pattern of [
|
||||
/ecc ito auth --json/, /ecc ito login/, /device URL\/code handoff/,
|
||||
/return control to the\s+originating agent/, /Timeout, denial, or revocation/,
|
||||
/Never place a key, token, or device code/,
|
||||
]) assert.match(skill, pattern);
|
||||
}],
|
||||
["documents the complete canonical lifecycle and validation bounds", () => {
|
||||
for (const pattern of [
|
||||
/inference preflight/, /inference deploy/, /inference status/,
|
||||
/inference logs/, /inference stop/, /owner\/model/, /pinned 7–64/,
|
||||
/1–168 hours/, /exact current\s+preflight amount/, /idempotency key/,
|
||||
]) assert.match(skill, pattern);
|
||||
}],
|
||||
["enforces separate confirmations, ambiguity recovery, and safe cleanup", () => {
|
||||
for (const pattern of [
|
||||
/separate state-changing actions/, /explicit\s+user confirmation immediately before each/,
|
||||
/do not deploy again blindly/, /provider timeout[\s\S]*not cached success/,
|
||||
/separate explicit teardown confirmation/, /must not cancel or delete.*compute\s+booking/,
|
||||
/cleanup.required=true/,
|
||||
]) assert.match(skill, pattern);
|
||||
}],
|
||||
["defines structured results and honest capability-state distinctions", () => {
|
||||
for (const field of [
|
||||
"status", "phase", "cluster", "authenticated", "eligible", "entitled",
|
||||
"model", "revision", "estimated cost", "deployment id", "health",
|
||||
"endpoint", "cleanup", "error code", "next action",
|
||||
]) assert.match(skill, new RegExp(field, "i"));
|
||||
assert.match(skill, /code existence,\s+local test pass, merge, deployment, and observed live behavior/);
|
||||
}],
|
||||
["registers package, module, dependency, capability, and full profile", () => {
|
||||
const module = json("manifests/install-modules.json").modules.find((item) => item.id === "ito-inference");
|
||||
assert.deepStrictEqual(module.paths, ["skills/ito-inference"]);
|
||||
assert.deepStrictEqual(module.dependencies, ["ito-compute"]);
|
||||
assert.strictEqual(module.defaultInstall, false);
|
||||
assert.strictEqual(module.stability, "beta");
|
||||
|
||||
const components = readJson("manifests/install-components.json").components;
|
||||
assert.deepStrictEqual(
|
||||
components.find((candidate) => candidate.id === "capability:ito-compute"),
|
||||
{
|
||||
id: "capability:ito-compute",
|
||||
family: "capability",
|
||||
description: "Authenticated Itô GPU inventory, RFQ, status, and explicitly gated node-qualification workflows through the separately installed canonical CLI.",
|
||||
modules: ["ito-compute"],
|
||||
}
|
||||
);
|
||||
|
||||
const profiles = readJson("manifests/install-profiles.json").profiles;
|
||||
assert.ok(profiles.full.modules.includes("ito-compute"));
|
||||
|
||||
const packageFiles = readJson("package.json").files;
|
||||
assert.ok(packageFiles.includes("skills/ito-inference/"));
|
||||
assert.ok(packageFiles.includes("skills/ito-training/"));
|
||||
}),
|
||||
assert.strictEqual(module.stability, "experimental");
|
||||
assert.ok(module.targets.includes("codex") && module.targets.includes("kimi"));
|
||||
assert.deepStrictEqual(json("manifests/install-components.json").components.find((item) => item.id === "capability:ito-inference").modules, ["ito-inference"]);
|
||||
assert.ok(json("manifests/install-profiles.json").profiles.full.modules.includes("ito-inference"));
|
||||
assert.ok(json("package.json").files.includes("skills/ito-inference/"));
|
||||
}],
|
||||
];
|
||||
|
||||
const failed = results.filter((passed) => !passed).length;
|
||||
console.log(`\nPassed: ${results.length - failed}`);
|
||||
let failed = 0;
|
||||
for (const [name, test] of tests) {
|
||||
try { test(); console.log(` ✓ ${name}`); }
|
||||
catch (error) { failed += 1; console.error(` ✗ ${name}: ${error.message}`); }
|
||||
}
|
||||
console.log(`Passed: ${tests.length - failed}`);
|
||||
console.log(`Failed: ${failed}`);
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
process.exitCode = failed ? 1 : 0;
|
||||
|
||||
@@ -118,7 +118,7 @@ async function main() {
|
||||
|
||||
const tests = [
|
||||
["forwards only the reviewed RFQ CLI surface to an explicit local executable", () => {
|
||||
for (const command of ["login", "logout", "auth", "find", "status"]) {
|
||||
for (const command of ["login", "logout", "auth", "find", "status", "inference"]) {
|
||||
const probe = makeItoProbe();
|
||||
try {
|
||||
const result = runCli(["ito", command], {
|
||||
@@ -241,8 +241,8 @@ async function main() {
|
||||
fs.rmSync(probe.directory, { recursive: true, force: true });
|
||||
}
|
||||
}],
|
||||
["forwards ITO_API_KEY directly to auth, find, and status without legacy mode", () => {
|
||||
for (const command of ["auth", "find", "status"]) {
|
||||
["forwards ITO_API_KEY directly to authenticated runtime commands without legacy mode", () => {
|
||||
for (const command of ["auth", "find", "status", "inference"]) {
|
||||
const probe = makeItoProbe();
|
||||
try {
|
||||
const result = runCli(["ito", command], {
|
||||
@@ -256,6 +256,33 @@ async function main() {
|
||||
}
|
||||
}
|
||||
}],
|
||||
["passes inference lifecycle arguments and explicit confirmation boundaries unchanged", () => {
|
||||
const probe = makeItoProbe();
|
||||
try {
|
||||
const args = [
|
||||
"ito", "inference", "deploy",
|
||||
"--cluster", "clu_1",
|
||||
"--model", "Qwen/Qwen3-8B",
|
||||
"--revision", "a1b2c3d4",
|
||||
"--engine", "vllm",
|
||||
"--max-runtime-hours", "2",
|
||||
"--confirm-cost-usd", "32.00",
|
||||
"--json",
|
||||
];
|
||||
const result = runCli(args, {
|
||||
ECC_ITO_CLI_EXECUTABLE: probe.executable,
|
||||
ITO_API_KEY: "ito_test_key",
|
||||
OPENAI_API_KEY: "must-not-cross",
|
||||
});
|
||||
assert.strictEqual(result.status, 0, result.stderr);
|
||||
const invocation = readInvocation(probe);
|
||||
assert.deepStrictEqual(invocation.argv, ["--json", ...args.slice(1, -1)]);
|
||||
assert.strictEqual(invocation.env.ITO_API_KEY, "ito_test_key");
|
||||
assert.strictEqual(invocation.env.OPENAI_API_KEY, undefined);
|
||||
} finally {
|
||||
fs.rmSync(probe.directory, { recursive: true, force: true });
|
||||
}
|
||||
}],
|
||||
["streams device login output before completion and propagates its exit status", async () => {
|
||||
const probe = makeItoProbe(7);
|
||||
try {
|
||||
@@ -473,14 +500,14 @@ async function main() {
|
||||
);
|
||||
}],
|
||||
["rejects unsupported browser, paper, and execution operations before spawning", () => {
|
||||
for (const command of ["rent", "lock", "purchase", "run", "inference", "mcp"]) {
|
||||
for (const command of ["rent", "lock", "purchase", "run", "mcp"]) {
|
||||
const probe = makeItoProbe();
|
||||
try {
|
||||
const result = runCli(["ito", command], {
|
||||
ECC_ITO_CLI_EXECUTABLE: probe.executable,
|
||||
});
|
||||
assert.notStrictEqual(result.status, 0, command);
|
||||
assert.match(result.stderr, /only login, logout, auth, find, status, and evals/i);
|
||||
assert.match(result.stderr, /only login, logout, auth, find, status, evals, and inference/i);
|
||||
assert.ok(!fs.existsSync(probe.log), `${command} must not spawn the Itô CLI`);
|
||||
} finally {
|
||||
fs.rmSync(probe.directory, { recursive: true, force: true });
|
||||
|
||||
Reference in New Issue
Block a user